From 08a1dcff561f9259747a7b16b536b9524c9deb8d Mon Sep 17 00:00:00 2001 From: "A. David Thyresson" Date: Tue, 7 Jun 2022 11:03:09 -0400 Subject: [PATCH 1/5] Mask errors, but include stack trasce in formatter --- packages/api-server/src/logFormatter/index.ts | 35 +++++++++++++++---- .../graphql-server/src/functions/graphql.ts | 10 +++--- .../src/plugins/useRedwoodLogger.ts | 14 ++++---- 3 files changed, 42 insertions(+), 17 deletions(-) diff --git a/packages/api-server/src/logFormatter/index.ts b/packages/api-server/src/logFormatter/index.ts index 6e1acc5c4a20..6058012ea2e4 100644 --- a/packages/api-server/src/logFormatter/index.ts +++ b/packages/api-server/src/logFormatter/index.ts @@ -176,14 +176,14 @@ export const LogFormatter = () => { output.push(formatTracing(tracing)) } - if (stack != null) { - output.push(formatStack(stack)) - } - if (err != null) { output.push(formatErrorProp(err)) } + if (stack != null) { + output.push(formatStack(stack)) + } + return output.filter(noEmpty).join(' ') } @@ -223,7 +223,20 @@ export const LogFormatter = () => { } const formatErrorProp = (errorPropValue: any) => { - return newline + JSON.stringify({ err: errorPropValue }, null, 2) + const errorType = errorPropValue['type'] || 'Error' + delete errorPropValue['message'] + delete errorPropValue['stack'] + delete errorPropValue['type'] + + return chalk.redBright( + newline + + newline + + `🚨 ${errorType} Info` + + newline + + newline + + JSON.stringify(errorPropValue, null, 2) + + newline + ) } const formatLevel = (level: any) => { @@ -321,7 +334,17 @@ export const LogFormatter = () => { } const formatStack = (stack: any) => { - return stack ? newline + stack : '' + return chalk.redBright( + stack + ? newline + + newline + + '🥞 Error Stack' + + newline + + newline + + stack + + newline + : '' + ) } const formatTracing = (data: any) => { diff --git a/packages/graphql-server/src/functions/graphql.ts b/packages/graphql-server/src/functions/graphql.ts index 72fe23947e44..93b9b69c365c 100644 --- a/packages/graphql-server/src/functions/graphql.ts +++ b/packages/graphql-server/src/functions/graphql.ts @@ -3,7 +3,6 @@ import { EnvelopError, FormatErrorHandler, GraphQLYogaError, - useMaskedErrors, } from '@graphql-yoga/common' import type { PluginOrDisabledPlugin } from '@graphql-yoga/common' @@ -163,14 +162,17 @@ export const createGraphQLHandler = ({ plugins.push(...extraPlugins) } - // Must be "last" in plugin chain so can process any data added to results and extensions + // Must be "last" in plugin chain, but before error masking + // so can process any data added to results and extensions plugins.push(useRedwoodLogger(loggerConfig)) - plugins.push(useMaskedErrors({ formatError, errorMessage: defaultError })) const yoga = createServer({ schema, plugins, - maskedErrors: false, + maskedErrors: { + formatError, + errorMessage: defaultError, + }, logging: logger, graphiql: isDevEnv ? { diff --git a/packages/graphql-server/src/plugins/useRedwoodLogger.ts b/packages/graphql-server/src/plugins/useRedwoodLogger.ts index e4d3a4c5523f..6b6c6116e21b 100644 --- a/packages/graphql-server/src/plugins/useRedwoodLogger.ts +++ b/packages/graphql-server/src/plugins/useRedwoodLogger.ts @@ -135,19 +135,19 @@ const logResult = error.originalError instanceof ForbiddenError) ) { envelopLogger.warn( - { - error, - }, + error, + `'${error?.extensions?.code || 'authentication'}' error '${ error.message }' occurred in ${operationName}` ) } else { envelopLogger.error( - { - error, - }, - error.message || `Error in GraphQL execution: ${operationName}` + error, + + error?.originalError?.message || + error.message || + `Error in GraphQL execution: ${operationName}` ) } }) From d3ca817d07565ab25e70a3496d5d0bdf51c5838e Mon Sep 17 00:00:00 2001 From: "A. David Thyresson" Date: Tue, 7 Jun 2022 11:20:33 -0400 Subject: [PATCH 2/5] Fix tests for new error attribute in log data --- .../src/plugins/__tests__/useRedwoodLogger.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/graphql-server/src/plugins/__tests__/useRedwoodLogger.test.ts b/packages/graphql-server/src/plugins/__tests__/useRedwoodLogger.test.ts index 437c0720e440..01d759f79ed1 100644 --- a/packages/graphql-server/src/plugins/__tests__/useRedwoodLogger.test.ts +++ b/packages/graphql-server/src/plugins/__tests__/useRedwoodLogger.test.ts @@ -198,7 +198,7 @@ describe('Populates context', () => { expect(errorLogStatement).toHaveProperty('level') expect(errorLogStatement).toHaveProperty('time') expect(errorLogStatement).toHaveProperty('msg') - expect(errorLogStatement).toHaveProperty('error') + expect(errorLogStatement).toHaveProperty('err') expect(errorLogStatement.name).toEqual('graphql-server') expect(errorLogStatement.level).toEqual(50) From b23d115082898cb460a6479e4d4cd0839ddf45a4 Mon Sep 17 00:00:00 2001 From: "A. David Thyresson" Date: Tue, 7 Jun 2022 11:25:19 -0400 Subject: [PATCH 3/5] Adds test to log stack traces --- .../__tests__/useRedwoodLogger.test.ts | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/packages/graphql-server/src/plugins/__tests__/useRedwoodLogger.test.ts b/packages/graphql-server/src/plugins/__tests__/useRedwoodLogger.test.ts index 01d759f79ed1..f3693b830e67 100644 --- a/packages/graphql-server/src/plugins/__tests__/useRedwoodLogger.test.ts +++ b/packages/graphql-server/src/plugins/__tests__/useRedwoodLogger.test.ts @@ -205,6 +205,29 @@ describe('Populates context', () => { expect(errorLogStatement.msg).toEqual('You are forbidden') }) + it('Should log an error with type and stack trace info when the resolver raises an exception', async () => { + const loggerConfig = { + logger, + options: {}, + } as LoggerConfig + + const testkit = createTestkit([useRedwoodLogger(loggerConfig)], testSchema) + + await testkit.execute(testErrorQuery, {}, {}) + + await watchFileCreated(logFile) + + const logStatements = parseLogFile(logFile) + + const errorLogStatement = logStatements.pop() + + expect(errorLogStatement).toHaveProperty('err') + expect(errorLogStatement.err).toHaveProperty('stack') + expect(errorLogStatement.err.type).toEqual('GraphQLError') + expect(errorLogStatement.err.path).toContain('forbiddenUser') + expect(errorLogStatement.err.message).toEqual('You are forbidden') + }) + it('Should not log filtered graphql operations', async () => { const loggerConfig = { logger, From 20adfed111a4e0361ede69c323e2d65b7f087e21 Mon Sep 17 00:00:00 2001 From: "A. David Thyresson" Date: Tue, 7 Jun 2022 11:32:38 -0400 Subject: [PATCH 4/5] Tests log error formatter --- .../src/__tests__/logFormatter.test.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/api-server/src/__tests__/logFormatter.test.ts b/packages/api-server/src/__tests__/logFormatter.test.ts index cd0d23e99367..4f71aa127583 100644 --- a/packages/api-server/src/__tests__/logFormatter.test.ts +++ b/packages/api-server/src/__tests__/logFormatter.test.ts @@ -175,4 +175,31 @@ describe('LogFormatter', () => { }) ).toMatch('"foo": "bar"') }) + + test('Should format error stack traces', () => { + expect( + logFormatter({ + level: 50, + err: { + message: 'This error has a stack traces', + stack: + 'A stack trace \n will have \n several lines \n at some line number \n at some code', + }, + }) + ).toMatch(/at some line number/) + }) + + test('Should format error and include the error type', () => { + expect( + logFormatter({ + level: 50, + err: { + type: 'GraphQL Error', + message: 'This error has a stack traces', + stack: + 'A stack trace \n will have \n several lines \n at some line number \n at some code', + }, + }) + ).toMatch(/GraphQL Error Info/) + }) }) From 0a5a1ab149de415e85ee8322b3c1f75c9c3bd574 Mon Sep 17 00:00:00 2001 From: Dominic Saadi Date: Wed, 15 Jun 2022 21:18:34 +0900 Subject: [PATCH 5/5] style: remove extra space between error and stack --- packages/api-server/src/logFormatter/index.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/api-server/src/logFormatter/index.ts b/packages/api-server/src/logFormatter/index.ts index 6058012ea2e4..9c8b2c704be5 100644 --- a/packages/api-server/src/logFormatter/index.ts +++ b/packages/api-server/src/logFormatter/index.ts @@ -336,13 +336,7 @@ export const LogFormatter = () => { const formatStack = (stack: any) => { return chalk.redBright( stack - ? newline + - newline + - '🥞 Error Stack' + - newline + - newline + - stack + - newline + ? newline + '🥞 Error Stack' + newline + newline + stack + newline : '' ) }