Skip to content

Commit cabf8a9

Browse files
committed
fix(handler): Stringify errors by exposing only the message
1 parent b8bdc71 commit cabf8a9

File tree

3 files changed

+33
-3
lines changed

3 files changed

+33
-3
lines changed

src/__tests__/handler.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,3 +175,16 @@ it('should replace the validation rules when providing a function', async () =>
175175
}
176176
`);
177177
});
178+
179+
it('should print plain errors in detail', async () => {
180+
const server = startTServer({});
181+
const url = new URL(server.url);
182+
const result = await fetch(url.toString(), {
183+
method: 'POST',
184+
headers: { 'content-type': 'application/json' },
185+
// missing body
186+
});
187+
await expect(result.text()).resolves.toMatchInlineSnapshot(
188+
`"{"errors":[{"message":"Unparsable JSON body"}]}"`,
189+
);
190+
});

src/handler.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
isExecutionResult,
2626
isGraphQLError,
2727
isObject,
28+
jsonErrorReplacer,
2829
} from './utils';
2930

3031
/**
@@ -726,7 +727,7 @@ export function makeResponse(
726727
!isGraphQLError(resultOrErrors)
727728
) {
728729
return [
729-
JSON.stringify({ errors: [resultOrErrors] }),
730+
JSON.stringify({ errors: [resultOrErrors] }, jsonErrorReplacer),
730731
{
731732
status: 400,
732733
statusText: 'Bad Request',
@@ -743,7 +744,7 @@ export function makeResponse(
743744
: null;
744745
if (errors) {
745746
return [
746-
JSON.stringify({ errors }),
747+
JSON.stringify({ errors }, jsonErrorReplacer),
747748
{
748749
...(acceptedMediaType === 'application/json'
749750
? {
@@ -765,7 +766,7 @@ export function makeResponse(
765766
}
766767

767768
return [
768-
JSON.stringify(resultOrErrors),
769+
JSON.stringify(resultOrErrors, jsonErrorReplacer),
769770
{
770771
status: 200,
771772
statusText: 'OK',

src/utils.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,19 @@ export function isAsyncIterable<T = unknown>(
6868
): val is AsyncIterable<T> {
6969
return typeof Object(val)[Symbol.asyncIterator] === 'function';
7070
}
71+
72+
/** @private */
73+
export function jsonErrorReplacer(_key: string, val: any) {
74+
if (
75+
val instanceof Error &&
76+
// GraphQL errors implement their own stringer
77+
!isGraphQLError(val)
78+
) {
79+
return {
80+
// name: val.name, name is included in message
81+
message: val.message,
82+
// stack: val.stack, can leak sensitive details
83+
};
84+
}
85+
return val;
86+
}

0 commit comments

Comments
 (0)