How to customize an errors with Fastify, Ajv and Schema?

332 views Asked by At

How can I customize an errors with Fastify, Ajv and Scheme? I need to format by:

{
    "message": "Bad request",
    "path": "/account/register",
    "status": 400,
    "timestamp": 1697094987,
    "errors": [
      { "key": "email", "value": "This value is not a valid email address."
    ]
}

When I try to:

const routes = async (app: Application) => {
  app.post('/accounts/register', { schema }, async (req: FastifyRequest, reply: FastifyReply) => {
    reply.code(200);
  });
};
   

I get an error with the following format:

{
    "statusCode": 400,
    "code": "FST_ERR_VALIDATION",
    "error": "Bad Request",
    "message": "body must have required property 'email'"
}
1

There are 1 answers

3
Manuel Spigolon On BEST ANSWER

If you need you can change the response error's message by setting the schemaErrorFormatter.

Nevertheless, you will not change the error output format.

Do change the output format you must:

const app = require('fastify')({
  logger: true,
  ajv: {
    customOptions: {
      allErrors: true
    }
  }
})

app.setErrorHandler(function (error, request, reply) {
  if (error.validation) {
    return reply.status(400).send({
      message: 'Bad request',
      path: request.url,
      status: 400,
      timestamp: Date.now(),
      errors: error.validation.map(err => ({
        key: err.params?.missingProperty || err.dataPath,
        value: err.message
      }))
    })
  }

  reply.status(500).send(error)
})

const schema = {
  body: {
    type: 'object',
    required: ['name', 'age'],
    properties: {
      name: { type: 'string' },
      age: { type: 'number' }
    }
  }
}

app.post('/', { schema }, async (request, reply) => {
  return request.body
})

app.listen({ port: 8080 })

Will produce this output:

{
  "message": "Bad request",
  "path": "/",
  "status": 400,
  "timestamp": 1697372490243,
  "errors": [
    {
      "key": "name",
      "value": "must have required property 'name'"
    },
    {
      "key": "age",
      "value": "must have required property 'age'"
    }
  ]
}