Repository: mcollina/fastify-gql
Pull request #259 (2020-08-21 07:20:14)

Expose defaultErrorFormatter
I would like to switch all thrown errors to 200, but preserve the built in error formatting capabilities by doing:

```
    errorFormatter: (err) => {
      err.statusCode = 200
      return defaultErrorFormatter(err)
    },
```

pscarey: Might be better to use this via:
```
    errorFormatter: (err) => {
      const response = defaultErrorFormatter(err)
      response.statusCode = 200
      return response
   },
```

Patch:
diff --git a/.gitignore b/.gitignore
index f519a3b..43e3659 100644
--- a/.gitignore
+++ b/.gitignore
@@ -66,3 +66,6 @@ package-lock.json
 
 # vscode
 .vscode/
+
+# intellij idea, webstorm
+.idea/
diff --git a/index.d.ts b/index.d.ts
index fcd0aca..5588c6d 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -184,7 +184,7 @@ export interface FastifyGQLCommonOptions {
     | {
         emitter?: object;
         verifyClient?: (
-          info: { origin: string; secure: boolean; req: IncomingMessage }, 
+          info: { origin: string; secure: boolean; req: IncomingMessage },
           next: (result: boolean, code?: number, message?: string, headers?: OutgoingHttpHeaders) => void
         ) => void,
         context?: (connection: SocketStream, request: FastifyRequest) => object | Promise<object>
@@ -217,7 +217,7 @@ export interface FastifyGQLCommonOptions {
 
 export type FastifyGQLOptions = FastifyGQLCommonOptions & (FastifyGQLGatewayOptions | FastifyGQLSchemaOptions)
 
-declare function fastifyGQL 
+declare function fastifyGQL
   (
     instance: FastifyInstance,
     opts: FastifyGQLOptions
@@ -276,6 +276,14 @@ declare namespace fastifyGQL {
     preparedOnly: (persistedQueries: object) => PeristedQueryProvider;
     automatic: (maxSize?: number) => PeristedQueryProvider;
   };
+
+  /**
+   * Default error formatter.
+   */
+  const defaultErrorFormatter: (
+    execution: ExecutionResult,
+    context: any
+  ) => { statusCode: number, response: ExecutionResult };
 }
 
 export default fastifyGQL;
diff --git a/index.js b/index.js
index fb3541e..0794f45 100644
--- a/index.js
+++ b/index.js
@@ -469,6 +469,7 @@ const plugin = fp(async function (app, opts) {
 })
 
 plugin.ErrorWithProps = ErrorWithProps
+plugin.defaultErrorFormatter = defaultErrorFormatter
 plugin.persistedQueryDefaults = persistedQueryDefaults
 
 module.exports = plugin


Test patch:
diff --git a/test/errors.js b/test/errors.js
index ccfeffd..08f7c99 100644
--- a/test/errors.js
+++ b/test/errors.js
@@ -443,6 +443,45 @@ test('errors - federated errors without locations, path and extensions', async (
   t.deepEqual(JSON.parse(jitres.payload), expectedResult)
 })
 
+test('errors - custom error formatter that uses default error formatter', async (t) => {
+  const schema = `
+      type Query {
+        bad: Int
+      }
+    `
+
+  const resolvers = {
+    bad: () => { throw new Error('Bad Resolver') }
+  }
+
+  const app = Fastify()
+
+  app.register(GQL, {
+    schema,
+    resolvers,
+    errorFormatter: (err, ctx) => {
+      t.ok(ctx)
+      t.is(ctx.app, app)
+      t.ok(ctx.reply)
+      const response = GQL.defaultErrorFormatter(err, ctx)
+      response.statusCode = 499
+      return response
+    }
+  })
+
+  await app.ready()
+
+  const res = await app.inject({
+    method: 'POST',
+    url: '/graphql',
+    body: { query: ' query { bad }' }
+  })
+
+  const body = JSON.parse(res.body)
+  t.equal(res.statusCode, 499)
+  t.equal(body.errors[0].message, 'Bad Resolver')
+})
+
 test('POST query with a resolver which which throws and a custom error formatter', async (t) => {
   const app = Fastify()
 
diff --git a/test/types/index.ts b/test/types/index.ts
index 602a7b4..6d00ece 100644
--- a/test/types/index.ts
+++ b/test/types/index.ts
@@ -63,6 +63,11 @@ app.register(fastifyGQL, {
   cache: true
 })
 
+app.register(fastifyGQL, {
+  schema,
+  errorFormatter: fastifyGQL.defaultErrorFormatter
+})
+
 app.register(async function (app) {
   app.graphql.extendSchema(`
     type Human {
@@ -134,6 +139,7 @@ makeGraphqlServer({ schema, resolvers })
 makeGraphqlServer({ schema, resolvers, validationRules: [] })
 makeGraphqlServer({ schema, resolvers, validationRules: [customValidationRule] })
 makeGraphqlServer({ schema, resolvers, validationRules: ({ variables, operationName, source }: { source: string, variables?: Record<string, any>, operationName?: string }) => [customValidationRule] })
+makeGraphqlServer({ schema, errorFormatter: fastifyGQL.defaultErrorFormatter })
 
 // Gateway mode