Skip to content

Commit 947292d

Browse files
committed
feat(graphql-yoga): add support for experimental error coordinate
feat(graphql-yoga): add support for experimental error coordinate
1 parent ffb02ee commit 947292d

File tree

6 files changed

+150
-120
lines changed

6 files changed

+150
-120
lines changed

package.json

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,7 @@
2222
"node": ">=18.0.0",
2323
"pnpm": ">=9.1.3"
2424
},
25-
"keywords": [
26-
"graphql",
27-
"server",
28-
"api",
29-
"graphql-server",
30-
"apollo"
31-
],
25+
"keywords": ["graphql", "server", "api", "graphql-server", "apollo"],
3226
"scripts": {
3327
"build": "pnpm --filter=@graphql-yoga/graphiql run build && pnpm --filter=@graphql-yoga/render-graphiql run build && pnpm --filter=graphql-yoga run generate-graphiql-html && bob build && pnpm --filter=graphql-yoga run inject-version",
3428
"build-website": "pnpm build && cd website && pnpm build",
@@ -91,9 +85,7 @@
9185
"wrangler": "4.46.0"
9286
},
9387
"lint-staged": {
94-
"packages/**/src/**/*.{ts,tsx}": [
95-
"cross-env \"ESLINT_USE_FLAT_CONFIG=false\" eslint --fix"
96-
],
88+
"packages/**/src/**/*.{ts,tsx}": ["cross-env \"ESLINT_USE_FLAT_CONFIG=false\" eslint --fix"],
9789
"**/*.{ts,tsx,graphql,yml,yaml,md,json,html,mdx,prettierignore,eslintignore,js,mjs,cjs,md}": [
9890
"prettier --write"
9991
]
@@ -107,6 +99,8 @@
10799
},
108100
"overrides": {
109101
"axios": "1.13.2",
102+
"@graphql-tools/executor": "1.5.0-alpha-20251113162628-fc5dd9a67f15da93da0f992ac3e357a9431c42bc",
103+
"@graphql-tools/utils": "10.11.0-alpha-20251113162628-fc5dd9a67f15da93da0f992ac3e357a9431c42bc",
110104
"estree-util-value-to-estree": "3.5.0",
111105
"eslint-plugin-unicorn": "56.0.1",
112106
"esbuild": "0.25.12",

packages/graphql-yoga/__tests__/error-masking.spec.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { inspect } from '@graphql-tools/utils';
22
import { createGraphQLError, createLogger, createSchema, createYoga } from '../src/index.js';
3+
import { useErrorCoordinate } from '../src/plugins/use-error-coordinate.js';
34
import { eventStream } from './utilities.js';
45

56
describe('error masking', () => {
@@ -859,4 +860,50 @@ describe('error masking', () => {
859860
}
860861
`);
861862
});
863+
864+
it.only('should mask experimental coordinate error attribute on production env', async () => {
865+
const yoga = createYoga({
866+
logging: false,
867+
// maskedErrors: {
868+
// isDev: true,
869+
// },
870+
maskedErrors: false,
871+
plugins: [useErrorCoordinate()],
872+
schema: createSchema({
873+
typeDefs: /* GraphQL */ `
874+
type Query {
875+
a: String!
876+
}
877+
`,
878+
resolvers: {
879+
Query: {
880+
a: () => {
881+
throw createGraphQLError('Test Error', { coordinate: 'Query.a' });
882+
},
883+
},
884+
},
885+
}),
886+
});
887+
888+
const response = await yoga.fetch('http://yoga/graphql', {
889+
method: 'POST',
890+
headers: {
891+
accept: 'application/graphql-response+json',
892+
'content-type': 'application/json',
893+
},
894+
body: JSON.stringify({ query: '{ a }' }),
895+
});
896+
897+
const body = await response.json();
898+
expect(response.status).toEqual(200);
899+
900+
expect(body).toMatchObject({
901+
errors: [
902+
{
903+
message: 'Test Error',
904+
coordinate: 'Query.a',
905+
},
906+
],
907+
});
908+
});
862909
});

packages/graphql-yoga/src/plugins/result-processor/stringify.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { GraphQLError } from 'graphql';
2-
import { createGraphQLError } from '@graphql-tools/utils';
2+
import { createGraphQLError, getSchemaCoordinate } from '@graphql-tools/utils';
33
import { isGraphQLError } from '../../error.js';
44
import { MaybeArray } from '../../types.js';
55
import { ExecutionResultWithSerializer } from '../types.js';
@@ -50,6 +50,7 @@ function omitInternalsFromError<E extends GraphQLError | Error | undefined>(err:
5050
path: err.path,
5151
originalError: omitInternalsFromError(err.originalError || undefined),
5252
extensions: Object.keys(extensions).length ? extensions : undefined,
53+
coordinate: getSchemaCoordinate(err),
5354
}) as E;
5455
}
5556
return err;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { ExecutionArgs } from '@graphql-tools/executor';
2+
import { Plugin } from './types.js';
3+
4+
export function useErrorCoordinate(): Plugin {
5+
return {
6+
onExecute({ args }) {
7+
(args as ExecutionArgs).schemaCoordinateInErrors = true;
8+
},
9+
};
10+
}

packages/graphql-yoga/src/utils/mask-error.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createGraphQLError } from '@graphql-tools/utils';
1+
import { createGraphQLError, getSchemaCoordinate } from '@graphql-tools/utils';
22
import { isGraphQLError, isOriginalGraphQLError } from '../error.js';
33
import { MaskError } from '../types.js';
44

@@ -42,6 +42,9 @@ export const maskError: MaskError = (
4242
if (error.extensions?.['http']) {
4343
errorExtensions['http'] = error.extensions['http'];
4444
}
45+
if (isDev) {
46+
errorOptions.coordinate = getSchemaCoordinate(error);
47+
}
4548
} else if (isDev) {
4649
errorExtensions['originalError'] = serializeError(error);
4750
}

0 commit comments

Comments
 (0)