Skip to content

fix(server): server error-registry sweep — route graphile middleware errors through the helper - #1565

Merged
pyramation merged 1 commit into
mainfrom
devin/1785487887-server-error-registry-sweep
Jul 31, 2026
Merged

fix(server): server error-registry sweep — route graphile middleware errors through the helper#1565
pyramation merged 1 commit into
mainfrom
devin/1785487887-server-error-registry-sweep

Conversation

@pyramation

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #1540, which introduced the canonical respondWithGraphQLError(res, ConstructiveError) helper (over the @constructive-io/errors registry) and converted the auth/captcha middleware. That fixed the "blank GraphQL Error:" class of bug where a hand-built body carried no top-level message for clients that render errors.map(e => e.message).join('; ').

This sweeps the remaining hand-rolled error responses on the GraphQL path — in middleware/graphile.ts, the PostGraphile handler middleware. Its short-circuit failures answered with a bare string or a REST-shaped { error: { code, message } } object, both of which a GraphQL client renders as an empty error. All three now go through the same helper:

-return res.status(500).send('Missing API info');
+respondWithGraphQLError(res, errors.INTERNAL_FAILURE({ details: 'Missing API info' }));
+return;

-return res.status(500).send('Missing service cache key');
+respondWithGraphQLError(res, errors.INTERNAL_FAILURE({ details: 'Missing service cache key' }));
+return;

 } catch (e: any) {
   if (!res.headersSent) {
-    return res.status(500).json({ error: { code: 'INTERNAL_ERROR', message: 'An unexpected error occurred' } });
+    respondWithGraphQLError(res, errors.INTERNAL_FAILURE({
+      details: isDev() ? e?.message ?? String(e) : 'An unexpected error occurred'
+    }));
+    return;
   }
   next(e);
 }

INTERNAL_FAILURE is internal-class, and the catch branch keeps raw error text out of production responses (dev-only detail) — matching #1540's auth catch exactly. Per the GraphQL-over-HTTP convention the helper responds 200 (the http: 500 hint travels in extensions), so these responses change from 500 to 200 with a proper { errors: [{ message, extensions: { code, class, http } }] } body.

Scope / call sites reviewed but intentionally left

The rest of the server's error responses are a deliberate REST/HTML transport layer, not GraphQL, so routing them through the GraphQL helper would change their externally-observable contract:

  • errors/api-errors.ts + middleware/error-handler.ts — the typed ApiError hierarchy and top-level Express handler; emit { error: { code, message } } JSON or HTML pages (404/50x) for REST clients.
  • middleware/api.ts — HTML error pages for domain/API resolution failures.
  • middleware/fn.ts — REST function-invocation API ({ error: '...' }, { invocationId }).
  • middleware/observability/*, middleware/favicon.ts, middleware/flush.ts — plain-text / REST utility endpoints.

No new registry codes were needed; INTERNAL_FAILURE already covers internal server errors.

Testing

  • graphql/server: tsc --noEmit clean; full suite 123/123 (incl. existing errors/__tests__/graphql-response.test.ts). The graphile middleware can't be imported under the repo's ts-jest config (grafast/graphql type resolution — same reason the existing graphile-device-token test reimplements its logic), so no new middleware unit test was added; the helper itself is covered by fix(server): route middleware GraphQL errors through the error registry #1540's tests.
  • Built the @constructive-io/graphql-server dependency subtree successfully. Note: a full pnpm build currently fails in an unrelated package (pgpm/transform, missing @pgsql/scripts types) — pre-existing on main, independent of this diff. A stale pnpm install was required first to link recently-added workspace deps.

Link to Devin session: https://app.devin.ai/sessions/e05316293f64436d8c9113443c1c7b76
Requested by: @pyramation

@pyramation pyramation self-assigned this Jul 31, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@pyramation
pyramation merged commit 99104d2 into main Jul 31, 2026
16 checks passed
@pyramation
pyramation deleted the devin/1785487887-server-error-registry-sweep branch July 31, 2026 09:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant