From 0704c2184ae139c1f4eb9611676c3fbcfb2e2860 Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Fri, 31 Jul 2026 08:51:27 +0000 Subject: [PATCH] fix(server): route graphile middleware GraphQL errors through the error registry --- graphql/server/src/middleware/graphile.ts | 24 +++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/graphql/server/src/middleware/graphile.ts b/graphql/server/src/middleware/graphile.ts index b4042f397..9cc96e341 100644 --- a/graphql/server/src/middleware/graphile.ts +++ b/graphql/server/src/middleware/graphile.ts @@ -1,7 +1,7 @@ import './types'; // for Request type import crypto from 'node:crypto'; -import { classify, type ErrorContext, parse } from '@constructive-io/errors'; +import { classify, errors, type ErrorContext, parse } from '@constructive-io/errors'; import type { ComputeConfig } from '@constructive-io/express-context'; import type { ConstructiveOptions } from '@constructive-io/graphql-types'; import { getNodeEnv } from '@pgpmjs/env'; @@ -17,12 +17,15 @@ import { getPgEnvOptions } from 'pg-env'; import { isGraphqlObservabilityEnabled } from '../diagnostics/observability'; import { HandlerCreationError } from '../errors/api-errors'; +import { respondWithGraphQLError } from '../errors/graphql-response'; import { AuthCookiePlugin } from '../plugins/auth-cookie-plugin'; import type { DatabaseSettings } from '../types'; import { observeGraphileBuild } from './observability/graphile-build-stats'; const maskErrorLog = new Logger('graphile:maskError'); +const isDev = (): boolean => getNodeEnv() === 'development'; + /** * GraphQL framework protocol codes. These originate in the GraphQL/grafast * transport layer (not in constructive-db), so they are not Constructive domain @@ -324,12 +327,17 @@ export const graphile = (opts: ConstructiveOptions): RequestHandler => { const api = req.api; if (!api) { log.error(`${label} Missing API info`); - return res.status(500).send('Missing API info'); + respondWithGraphQLError(res, errors.INTERNAL_FAILURE({ details: 'Missing API info' })); + return; } const key = req.svc_key; if (!key) { log.error(`${label} Missing service cache key`); - return res.status(500).send('Missing service cache key'); + respondWithGraphQLError( + res, + errors.INTERNAL_FAILURE({ details: 'Missing service cache key' }) + ); + return; } const { dbname, anonRole, roleName, schema } = api; const schemaLabel = schema?.join(',') || 'unknown'; @@ -431,9 +439,13 @@ export const graphile = (opts: ConstructiveOptions): RequestHandler => { } catch (e: any) { log.error(`${label} PostGraphile middleware error`, e); 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); }