Skip to content

Commit b137c8e

Browse files
committed
use toJSON to maske coordinates
1 parent e5cca5a commit b137c8e

File tree

1 file changed

+37
-4
lines changed

1 file changed

+37
-4
lines changed

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

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,21 @@
1+
import { GraphQLError, GraphQLFormattedError } from 'graphql';
12
import { createGraphQLError, getSchemaCoordinate } from '@graphql-tools/utils';
23
import { isGraphQLError, isOriginalGraphQLError } from '../error.js';
34
import { MaskError } from '../types.js';
45

6+
// We override the `toJSON` function to mask coordinate, because otherwise, it will be entirely
7+
// masked for plugins after the onExecuteDone phase (which have an impact for telemetry for example)
8+
function toJsonWithoutCoordinate(this: GraphQLError): GraphQLFormattedError {
9+
const toJSON: typeof GraphQLError.prototype.toJSON =
10+
(this as { _originalToJSON?: typeof GraphQLError.prototype.toJSON })._originalToJSON ??
11+
GraphQLError.prototype.toJSON;
12+
const json = toJSON.apply(this);
13+
// @ts-expect-error coordinate is readonly
14+
delete json.coordinate;
15+
16+
return json;
17+
}
18+
519
function serializeError(error: unknown) {
620
if (isGraphQLError(error)) {
721
return error.toJSON();
@@ -22,6 +36,12 @@ export const maskError: MaskError = (
2236
isDev = globalThis.process?.env?.['NODE_ENV'] === 'development',
2337
) => {
2438
if (isOriginalGraphQLError(error)) {
39+
if (!isDev) {
40+
Object.defineProperties(error, {
41+
toJSON: { value: toJsonWithoutCoordinate },
42+
_originalToJSON: { value: error.toJSON },
43+
});
44+
}
2545
return error;
2646
}
2747
const errorExtensions: Record<string, unknown> = {
@@ -36,18 +56,31 @@ export const maskError: MaskError = (
3656
errorOptions.source = error.source;
3757
errorOptions.positions = error.positions;
3858
errorOptions.path = error.path;
59+
errorOptions.coordinate = getSchemaCoordinate(error);
3960
if (isDev && error.originalError) {
4061
errorExtensions['originalError'] = serializeError(error.originalError);
4162
}
4263
if (error.extensions?.['http']) {
4364
errorExtensions['http'] = error.extensions['http'];
4465
}
45-
if (isDev) {
46-
errorOptions.coordinate = getSchemaCoordinate(error);
47-
}
4866
} else if (isDev) {
4967
errorExtensions['originalError'] = serializeError(error);
5068
}
5169

52-
return createGraphQLError(message, errorOptions);
70+
const maskedError = createGraphQLError(message, errorOptions);
71+
72+
if (!isDev) {
73+
Object.defineProperties(maskedError, {
74+
toJSON: { value: toJsonWithoutCoordinate },
75+
_originalToJSON: { value: maskedError.toJSON },
76+
});
77+
if (maskedError.extensions['originalError'] instanceof GraphQLError) {
78+
Object.defineProperties(maskedError.extensions['originalError'], {
79+
toJSON: { value: toJsonWithoutCoordinate },
80+
_originalToJSON: { value: maskedError.extensions['originalError'].toJSON },
81+
});
82+
}
83+
}
84+
85+
return maskedError;
5386
};

0 commit comments

Comments
 (0)