Add extensive error handling+reporting for API calls

This commit is contained in:
2026-05-01 18:13:52 -04:00
parent 3058d4f968
commit b669e03d60

View File

@@ -11,8 +11,12 @@ Pebble.addEventListener("appmessage", function (dict) {
if (dict.payload["PKJS_SLEEP_TIMESTAMP"]) { if (dict.payload["PKJS_SLEEP_TIMESTAMP"]) {
const sleepTimestamp = dict.payload["PKJS_SLEEP_TIMESTAMP"]; const sleepTimestamp = dict.payload["PKJS_SLEEP_TIMESTAMP"];
const cfg = JSON.parse(localStorage.getItem('clay-settings')); const cfg = JSON.parse(localStorage.getItem('clay-settings'));
// TODO report last episode as "Configure app settings!" if CLAY_API_HOST, CLAY_API_KEY, or CLAY_USER is empty
// TODO use API to dynamically determine user (prompt on watch) // report to user if some configuration is missing
if (cfg.CLAY_API_HOST == "" || cfg.CLAY_API_KEY == "" || cfg.CLAY_USER == "") {
Pebble.sendAppMessage({ PKJS_LAST_WATCHED: "SOME APP SETTINGS ARE UNSET" });
}
if (cfg.CLAY_API_IS_JELLYFIN == true) { if (cfg.CLAY_API_IS_JELLYFIN == true) {
callAPI(cfg.CLAY_API_HOST + "/System/ActivityLog/Entries?hasUserId=true&limit=100", cfg.CLAY_API_KEY, true, cfg.CLAY_USER, sleepTimestamp * 1000); callAPI(cfg.CLAY_API_HOST + "/System/ActivityLog/Entries?hasUserId=true&limit=100", cfg.CLAY_API_KEY, true, cfg.CLAY_USER, sleepTimestamp * 1000);
} else { } else {
@@ -27,9 +31,51 @@ Pebble.addEventListener("appmessage", function (dict) {
function callAPI(fullURL, apiKey, isJellyfin, trackedUser, sleepTimestamp) { function callAPI(fullURL, apiKey, isJellyfin, trackedUser, sleepTimestamp) {
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
let didReportError = false;
function reportApiError(message) {
if (didReportError) {
return;
}
didReportError = true;
Pebble.sendAppMessage({ PKJS_LAST_WATCHED: message });
}
xhr.onerror = function () {
reportApiError("API UNREACHABLE");
};
xhr.ontimeout = function () {
reportApiError("API TIMEOUT");
};
xhr.onreadystatechange = function () { xhr.onreadystatechange = function () {
if (xhr.readyState === 4) { if (xhr.readyState === 4) {
const resp = JSON.parse(xhr.responseText); if (xhr.status === 0) {
reportApiError("API UNREACHABLE");
return;
}
if (xhr.status < 200 || xhr.status >= 300) {
if (xhr.status == 401) {
reportApiError("API ERROR: " + xhr.status + " (CHECK API KEY)");
} else {
reportApiError("API ERROR: " + xhr.status);
}
return;
}
if (!xhr.responseText) {
reportApiError("API EMPTY RESPONSE");
return;
}
let resp;
try {
resp = JSON.parse(xhr.responseText);
} catch (e) {
reportApiError("API INVALID RESPONSE");
return;
}
if (resp && ((isJellyfin === true && Array.isArray(resp.Items)) || (isJellyfin === false && Array.isArray(resp.response.data.data)))) { if (resp && ((isJellyfin === true && Array.isArray(resp.Items)) || (isJellyfin === false && Array.isArray(resp.response.data.data)))) {
let delta; let delta;
let bestDelta = Infinity; let bestDelta = Infinity;
@@ -66,14 +112,16 @@ function callAPI(fullURL, apiKey, isJellyfin, trackedUser, sleepTimestamp) {
} }
if (lastWatched != "") { if (lastWatched != "") {
//console.log("Last watched: " + lastWatched); //console.log("Last watched: " + lastWatched);
var dict = { 'PKJS_LAST_WATCHED': lastWatched } Pebble.sendAppMessage({ PKJS_LAST_WATCHED: lastWatched });
Pebble.sendAppMessage(dict); } else {
Pebble.sendAppMessage({ PKJS_LAST_WATCHED: "NO WATCH HISTORY FOUND FOR USER " + trackedUser });
} }
} }
} }
}; };
xhr.open("GET", fullURL, true); xhr.open("GET", fullURL, true);
xhr.timeout = 8000;
xhr.setRequestHeader("Accept", "application/json"); xhr.setRequestHeader("Accept", "application/json");
if (isJellyfin) { if (isJellyfin) {
xhr.setRequestHeader("Authorization", 'MediaBrowser Token="' + apiKey + '"'); xhr.setRequestHeader("Authorization", 'MediaBrowser Token="' + apiKey + '"');