Repository navigation
Replace the hand-rolled isErrorResponse guard with Zod validation #2173
Description
Context
isErrorResponse is a hand-written type predicate on a network boundary, which is exactly where AGENTS.md asks for Zod. #2162 already had to fix a null dereference in it, and the fix left a cast behind:
function isErrorResponse(value: unknown): value is ErrorResponse {
if (typeof value !== "object" || value === null) {
return false;
}
const record = value as Record<string, unknown>;
return !!(record.code && record.detailedMessage);
}A schema makes the null case unrepresentable rather than guarded, removes the cast, and makes the contract explicit instead of implied by two truthiness checks.
Task
Blocked on #2172, which establishes the actual shape to encode.
- Replace the predicate with a Zod schema and a
safeParseat the boundary, using the shape Establish the shape of database error responses across engines and Neptune versions #2172 recommends. - Reconcile with
utils/extractErrorMessage.tsso there is one definition of an error body rather than two that disagree. - Delete
isErrorResponseand itsErrorResponsetype if the schema's inferred type supersedes them. - While touching all 14 call sites, evaluate collapsing them. Every one runs the same ritual and they do not agree on it:
gremlin/rawQuery.ts,sparql/rawquery.ts, andsparql/parseAndMapQuads.tslog before throwing, whileopenCypher/neighborCounts.tsandgremlin/keywordSearch/index.tsthrow silently. A shared parse-then-check helper would make the logging uniform in one place and remove 14 copies of the branch.
isErrorResponse.test.ts covers the object, missing-field, null, and undefined cases and should keep passing, or move to the schema's own tests.
Relationship to #2078
Siblings, not duplicates. #2078 validates the success response shapes at the connector fetch boundary (Raw*Response, entity shapes, branded labels). This issue validates the error envelope at the same boundary and the same call sites. Whoever picks up either should read the other, and landing them together may be cheaper than separately.
Related Issues
- Part of Overhaul error handling across the app #2171
- Blocked by Establish the shape of database error responses across engines and Neptune versions #2172
- Related to Validate connector fetch boundaries with Zod and brand label types #2078
- Related to Consolidate domain error types behind a shared base class #2163
- Originated from Upgrade the Oxc toolchain and resolve #2150 lint findings #2162
Important
Internal only — this issue is maintained by the core team and is not accepting external contributions.
Activity