Skip to content

Avoiding trying try/catch block when handling errors in Express? #200

@abdellani

Description

@abdellani

Hi

I was reading this blog ( https://github.com/rwieruch/blog_robinwieruch_content/blob/master/blog/node-express-error-handling/index.md ) about the handling errors in Express JS. Before sharing my note, I want to thank you for your efforts.

When you said: Fortunately we don't need to use a try/catch block but just use the promise's catch method instead.

router.post('/', async (req, res, next) => {
  const message = await req.context.models.Message.create({
    text: req.body.text,
    user: req.context.me.id,
  }).catch(next);

  return res.send(message);
});

I think that this is not correct. When the middleware finishes sending the error to the client, Express will try to run res.send(message). This will raise another exception because the code is trying to send another response to the client.
please correct me if I'm wrong.
Here's a copy of the error :

node:internal/process/promises:245
          triggerUncaughtException(err, true /* fromPromise */);
          ^

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at new NodeError (node:internal/errors:329:5)
    at ServerResponse.setHeader (node:_http_outgoing:579:11)
    at ServerResponse.header (/home/.../node_modules/express/lib/response.js:771:10)
    at ServerResponse.send (/home/.../node_modules/express/lib/response.js:170:12)
    at ServerResponse.json (/home/.../node_modules/express/lib/response.js:267:15)
    at eval (webpack:///./src/controllers/users.js?:34:18)
    at processTicksAndRejections (node:internal/process/task_queues:94:5)
    at async createUser (webpack:///./src/controllers/users.js?:31:3) {
  code: 'ERR_HTTP_HEADERS_SENT'
}
[nodemon] app crashed - waiting for file changes before starting...

I think the correct way to do it, is wether by using try/catch block or by moving the res.send into then before the catch block, it should look like:

router.post('/', async (req, res, next) => {
  req.context.models.Message.create({
    text: req.body.text,
    user: req.context.me.id,
  }).then(()=>res.send(message))
  .catch(next);
});

The same thing for the following code.

...

import { BadRequestError } from '../utils/errors';

...

router.post('/', async (req, res, next) => {
  const message = await req.context.models.Message.create({
    text: req.body.text,
    user: req.context.me.id,
  }).catch((error) => next(new BadRequestError(error)));

  return res.send(message);
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions