{
- const resp = await fetch(path, {
- method,
- credentials: "include", // send/receive the signed session cookie
- headers: body !== undefined ? { "Content-Type": "application/json" } : undefined,
- body: body !== undefined ? JSON.stringify(body) : undefined,
- });
+ let resp: Response;
+ try {
+ resp = await fetch(path, {
+ method,
+ credentials: "include", // send/receive the signed session cookie
+ headers: body !== undefined ? { "Content-Type": "application/json" } : undefined,
+ body: body !== undefined ? JSON.stringify(body) : undefined,
+ });
+ } catch {
+ const err: ApiError = { error: "Can't reach the server. Check your connection.", status: 0 };
+ notifyError(err);
+ throw err;
+ }
const text = await resp.text();
- const data: unknown = text ? JSON.parse(text) : {};
+ let data: unknown = {};
+ if (text) {
+ try {
+ data = JSON.parse(text);
+ } catch {
+ data = {}; // non-JSON body (e.g. a proxy error page) — fall through to status handling
+ }
+ }
if (!resp.ok) {
const message =
typeof data === "object" && data !== null && "error" in data
? String((data as { error: unknown }).error)
- : "Request failed.";
+ : "Something went wrong. Please try again.";
const err: ApiError = { error: message, status: resp.status };
+ if (resp.status >= 500) notifyError(err);
throw err;
}
diff --git a/frontend/src/components/AppShell.vue b/frontend/src/components/AppShell.vue
index 7986021..950f77a 100644
--- a/frontend/src/components/AppShell.vue
+++ b/frontend/src/components/AppShell.vue
@@ -8,7 +8,6 @@ import { useUiStore } from "../stores/ui";
import CommandPalette from "./CommandPalette.vue";
import Icon from "./Icon.vue";
import LabelsModal from "./LabelsModal.vue";
-import ToastHost from "./ToastHost.vue";
import { NOTE_SWATCH_CLASSES, type NoteColor } from "../notes/colors";
const route = useRoute();
@@ -297,8 +296,6 @@ async function signOut() {
-
-
{{ ui.toast.message }}