fix(client): full crash if server fails to obtain list of widgets

This commit is contained in:
Elian Doran 2025-12-20 19:18:50 +02:00
parent fa8ff4bfbf
commit d036bf0870
No known key found for this signature in database
3 changed files with 43 additions and 32 deletions

View File

@ -98,36 +98,44 @@ export class WidgetsByParent {
} }
async function getWidgetBundlesByParent() { async function getWidgetBundlesByParent() {
const scriptBundles = await server.get<Bundle[]>("script/widgets");
const widgetsByParent = new WidgetsByParent(); const widgetsByParent = new WidgetsByParent();
for (const bundle of scriptBundles) { try {
let widget; const scriptBundles = await server.get<Bundle[]>("script/widgets");
try { for (const bundle of scriptBundles) {
widget = await executeBundle(bundle); let widget;
if (widget) {
widget._noteId = bundle.noteId; try {
widgetsByParent.add(widget); widget = await executeBundle(bundle);
if (widget) {
widget._noteId = bundle.noteId;
widgetsByParent.add(widget);
}
} catch (e: any) {
const noteId = bundle.noteId;
const note = await froca.getNote(noteId);
toastService.showPersistent({
id: `custom-script-failure-${noteId}`,
title: t("toast.bundle-error.title"),
icon: "bx bx-error-circle",
message: t("toast.bundle-error.message", {
id: noteId,
title: note?.title,
message: e.message
})
});
logError("Widget initialization failed: ", e);
continue;
} }
} catch (e: any) {
const noteId = bundle.noteId;
const note = await froca.getNote(noteId);
toastService.showPersistent({
id: `custom-script-failure-${noteId}`,
title: t("toast.bundle-error.title"),
icon: "bx bx-error-circle",
message: t("toast.bundle-error.message", {
id: noteId,
title: note?.title,
message: e.message
})
});
logError("Widget initialization failed: ", e);
continue;
} }
} catch (e) {
toastService.showPersistent({
title: t("toast.widget-list-error.title"),
message: e.toString(),
icon: "bx bx-error-circle"
});
} }
return widgetsByParent; return widgetsByParent;

View File

@ -133,11 +133,11 @@ async function call<T>(method: string, url: string, componentId?: string, option
}; };
ipc.send("server-request", { ipc.send("server-request", {
requestId: requestId, requestId,
headers: headers, headers,
method: method, method,
url: `/${window.glob.baseApiUrl}${url}`, url: `/${window.glob.baseApiUrl}${url}`,
data: data data
}); });
})) as any; })) as any;
} else { } else {
@ -161,7 +161,7 @@ function ajax(url: string, method: string, data: unknown, headers: Headers, sile
const options: JQueryAjaxSettings = { const options: JQueryAjaxSettings = {
url: window.glob.baseApiUrl + url, url: window.glob.baseApiUrl + url,
type: method, type: method,
headers: headers, headers,
timeout: 60000, timeout: 60000,
success: (body, textStatus, jqXhr) => { success: (body, textStatus, jqXhr) => {
const respHeaders: Headers = {}; const respHeaders: Headers = {};
@ -288,8 +288,8 @@ async function reportError(method: string, url: string, statusCode: number, resp
t("server.unknown_http_error_content", { statusCode, method, url, message: messageStr }), t("server.unknown_http_error_content", { statusCode, method, url, message: messageStr }),
15_000); 15_000);
} }
const { throwError } = await import("./ws.js"); const { logError } = await import("./ws.js");
throwError(`${statusCode} ${method} ${url} - ${message}`); logError(`${statusCode} ${method} ${url} - ${message}`);
} }
} }

View File

@ -22,6 +22,9 @@
"bundle-error": { "bundle-error": {
"title": "Failed to load a custom script", "title": "Failed to load a custom script",
"message": "Script from note with ID \"{{id}}\", titled \"{{title}}\" could not be executed due to:\n\n{{message}}" "message": "Script from note with ID \"{{id}}\", titled \"{{title}}\" could not be executed due to:\n\n{{message}}"
},
"widget-list-error": {
"title": "Failed to obtain the list of widgets from the server"
} }
}, },
"add_link": { "add_link": {