refactor(frontend): extract extractErrorCode() helper to eliminate repeated as-unknown-as type assertions #113
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
The pattern
(result.error as unknown as { code?: string })?.codeappears 10+ times across load functions. Double-casting throughunknownmeans TypeScript cannot catch shape mismatches — it is the equivalent ofanywith extra steps.Fix
Define the backend error shape once in
src/lib/api.server.ts:Then replace all call sites:
Acceptance Criteria
ApiErrorinterface andextractErrorCode()defined inapi.server.tsas unknown as { code?: string }occurrences replaced across all load functionsnpm run checkpasses cleanly👨💻 Felix Brandt — Senior Fullstack Developer
Questions & Observations
api.server.tsis good — it's the boundary file where errors originate. Make sure it's exported so any load function can import it directly without going through a barrel file.ApiErrorinterface should be exported too. Even if it's only used internally now, it gives TypeScript something to check against if the backend error shape ever changes.Suggestions
grep -r "as unknown as" frontend/src— the result should be empty. If not, you missed a call site.npm run checkmust pass cleanly as the acceptance criterion states — add it to the PR checklist.🔒 Nora "NullX" Steiner — Application Security Engineer
No direct security concerns here — this is a type-safety refactor with no security-sensitive behaviour change.
One observation worth noting: the
as unknown as { code?: string }pattern is type-system evasion. It doesn't create a vulnerability today, but it does mean TypeScript cannot catch a future case where the backend changes its error shape and the frontend silently passesundefinedtogetErrorMessage()— potentially hiding an error that should be surfaced to the user. TheApiErrorinterface makes this one step more robust, though it's still a runtime shape assumption. If the backend ever adds a formal problem+JSON response body (RFC 7807), a stricter validation at the boundary would be worth considering then.No security findings to add — this is the right thing to do for code health.
🧪 Sara Holt — QA Engineer & Test Strategist
Test Strategy
This is a pure unit test target — a small, pure function with no side effects.
Vitest unit tests (
extractErrorCode.test.ts):Observations
as unknownorigin — we know nothing about the runtime shape.🏗️ Markus Keller — Application Architect
Questions & Observations
api.server.tsis the right home — it's the module that wraps all backend communication, so error shape knowledge belongs there. Don't put this in a separateutils.tsbarrel; keep it co-located withcreateApiClient.ApiErrorinterface should be exported. Load functions in separate route files will need to import it if they ever want to type a caught error explicitly — and keeping it importable from one canonical location is cleaner than each route re-declaring the shape.Suggestions
getErrorMessageworks). Keep it atomic.CODESTYLE.mdor the API client section inCLAUDE.mdthatextractErrorCodeis the canonical way to read the error code — so future developers don't re-introduce the pattern.🎨 Leonie Voss — UI/UX Designer & Accessibility Strategist
No UI/UX concerns from my angle — this is a backend TypeScript utility refactor with no user-facing rendering changes. No visual components, no interaction patterns, and no i18n strings are affected.
I verified that
extractErrorCodeis a server-side helper inapi.server.tsand does not touch any Svelte components or rendered output. Clean from my perspective.🚀 Tobias Wendt — DevOps & Platform Engineer
No DevOps or infrastructure concerns here — this is a pure frontend TypeScript refactor with no deployment, config, or infrastructure impact.
npm run checkpassing is the only gate needed. CI will catch it automatically.