You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It returns a bare Error carrying only a message. Two things are thrown away:
res.status — so no caller can distinguish a 409 from a 500, or a 403 from a 404, without string-matching the message.
Everything else in the body. The dashboards API deliberately puts structured data there. src/routes/api/v1/orgs/[org_id]/dashboards/_shared.ts returns currentVersion on a version conflict, and its comment says why: "so a save-conflict dialog can offer more than 'someone changed this, reload'". warnings is discarded the same way — and feat(dashboards): gate auto-refresh on owner/admin rather than any writer #60 requires a clamp to be "a visible warning, not a silent change".
So the one place that produces a rich error and the one place that consumes it are connected by a function that flattens it.
Why it matters now
src/routes/(app)/d/[uid]/+page.svelte had to bypasscloudApi entirely and hand-roll its fetch to get at status, currentVersion and warnings. That is a second HTTP path to the same endpoint, which is how the two diverge later.
Fix
Give apiError a typed error that keeps what the response said:
Then add updateDashboardRequest(orgId, uid, model, expectedVersion) alongside the existing createDashboardRequest, returning { dashboard, warnings }, and migrate the view page onto it so there is one path again.
Good first issue notes
Self-contained: one file plus one call site. Read createDashboardRequest and deleteDashboardRequest in the same file for the shape to follow, and _shared.ts's toErrorResponse for what the server actually sends.
Two things to be careful about:
Every existing throw await apiError(...) call site must keep working.ApiError extends Error, so err instanceof Error and err.message stay true — check the catch blocks that do err instanceof Error ? err.message : ... before assuming.
Do not log or render body wholesale. Some endpoints put upstream detail in error bodies; the view page shows message and currentVersion and nothing else. The same rule is documented on QueryError.detail in src/lib/dashboard/queryRunner.ts.
Found while wiring #35's save flow.
The problem
src/lib/cloudApi.ts:It returns a bare
Errorcarrying only a message. Two things are thrown away:res.status— so no caller can distinguish a 409 from a 500, or a 403 from a 404, without string-matching the message.src/routes/api/v1/orgs/[org_id]/dashboards/_shared.tsreturnscurrentVersionon a version conflict, and its comment says why: "so a save-conflict dialog can offer more than 'someone changed this, reload'".warningsis discarded the same way — and feat(dashboards): gate auto-refresh on owner/admin rather than any writer #60 requires a clamp to be "a visible warning, not a silent change".So the one place that produces a rich error and the one place that consumes it are connected by a function that flattens it.
Why it matters now
src/routes/(app)/d/[uid]/+page.sveltehad to bypasscloudApientirely and hand-roll itsfetchto get atstatus,currentVersionandwarnings. That is a second HTTP path to the same endpoint, which is how the two diverge later.Fix
Give
apiErrora typed error that keeps what the response said:Then add
updateDashboardRequest(orgId, uid, model, expectedVersion)alongside the existingcreateDashboardRequest, returning{ dashboard, warnings }, and migrate the view page onto it so there is one path again.Good first issue notes
Self-contained: one file plus one call site. Read
createDashboardRequestanddeleteDashboardRequestin the same file for the shape to follow, and_shared.ts'stoErrorResponsefor what the server actually sends.Two things to be careful about:
throw await apiError(...)call site must keep working.ApiError extends Error, soerr instanceof Erroranderr.messagestay true — check thecatchblocks that doerr instanceof Error ? err.message : ...before assuming.bodywholesale. Some endpoints put upstream detail in error bodies; the view page showsmessageandcurrentVersionand nothing else. The same rule is documented onQueryError.detailinsrc/lib/dashboard/queryRunner.ts.