Skip to content

Commit 89d3ba3

Browse files
committed
feat(graphql-yoga): add support for experimental error coordinate
1 parent 8fe8b0e commit 89d3ba3

File tree

6 files changed

+146
-85
lines changed

6 files changed

+146
-85
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@
105105
"package-up": "patches/package-up.patch"
106106
},
107107
"overrides": {
108-
"@graphql-tools/executor": "1.5.0-alpha-20251027130952-40022d4f527c54b1c783614d6b2c21c39e26556b",
109-
"@graphql-tools/utils": "10.10.0-alpha-20251027130952-40022d4f527c54b1c783614d6b2c21c39e26556b",
108+
"@graphql-tools/executor": "1.5.0-alpha-20251113162628-fc5dd9a67f15da93da0f992ac3e357a9431c42bc",
109+
"@graphql-tools/utils": "10.11.0-alpha-20251113162628-fc5dd9a67f15da93da0f992ac3e357a9431c42bc",
110110
"axios": "1.12.2",
111111
"estree-util-value-to-estree": "3.5.0",
112112
"eslint-plugin-unicorn": "56.0.1",

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)