Search code examples
javascriptfastifyajv

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


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'"
}

Solution

  • 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'"
        }
      ]
    }