Search code examples
node.jskoa2

Nodejs - how to catch thrown error and format it?


I don't quite understand how to catch the error that I throw somewhere deep inside my routes, e.g.:

// put
router.put('/', async (ctx, next) => {
  let body = ctx.request.body || {}
  if (body._id === undefined) {
    // Throw the error.
    ctx.throw(400, '_id is required.')
  }
})

I will get when _id is not provided:

_id is required.

But I don't throw it like in plain text. I would prefer catching it at the top level and then formatting it, e.g.:

{
  status: 400.
  message: '_id is required.'
}

According to the doc:

app.use(async (ctx, next) => {
    try {
      await next()
    } catch (err) {
      ctx.status = err.status || 500

      console.log(ctx.status)
      ctx.body = err.message
      
      ctx.app.emit('error', err, ctx)
    }
  })

But even without that try catch in my middleware, I still get _id is required.

Any ideas?


Solution

  • Throw an error with needed status code:

    ctx.throw(400, '_id is required.');
    

    And use default error handler to format the error response:

    app.use(async (ctx, next) => {
      try {
        await next();
      } catch (err) {
        ctx.status = err.statusCode || err.status || 500;
        ctx.body = {
          status: ctx.status,
          message: err.message
        };
      }
    });