Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

276
Views
[ExpressJs]: Custom Error handler do not catch exceptions

I am creating a router with ExpressJs (using TypeScript) and thrown exceptions are not caught by my custom error handler, here is the code:

In index.ts file (which is the main):

import express, { Express } from 'express';
import cors from 'cors';
import { config } from '~/utils/config';
import { NotFoundRoute } from '~/middlewares/NotFound';
import { ExceptionHandler } from '~/middlewares/ExceptionHandler';
import { usersRouter } from '~/controllers/users';

const app: Express = express();
app.use(express.json());
app.use(cors());
app.use('/users', usersRouter);
app.all('*', NotFoundRoute);
app.use(ExceptionHandler);

app.listen(config.port, () => console.log("API is running on port " + config.port));

The custom exception handler:

import { NextFunction, Request, Response } from 'express';

export const ExceptionHandler = (err: any, req: Request, res: Response, next: NextFunction) => {
  if (res.headersSent)
    return next(err);

  if (err.status && err.message) {
    res.status(err.status).send({ error: err.message });
  } else
    return res.status(500).send({ message: "Internal Server Error" });
}

The router that is problematic (where InternalServerError is not caught by the above):

import { Request, Response, Router } from 'express';
import { User } from '~/schemas/User';
import { InternalServerError } from '~/errors/InternalServerError';

const usersRouter = Router();

usersRouter.get('/', async (req: Request, res: Response) => {
  try {
    const users = await User.find({});
    res.status(200).send(users);
  } catch (err) {
    res.status(500).send({ message: "Failed to fetch users"});
  }
})

usersRouter.post('/register', async (req: Request, res: Response) => {
  try {
    const { email, password } = req.body;
    if (!email || !password)
      res.status(403).send({ message: "Bad Request"});
    const newUser = User.createUser({ email, password });
    await newUser.save();
    res.status(201).send(newUser);
  } catch (err) {
    throw new InternalServerError();
  }
})

export { usersRouter };

All my exception are not caught which means that it is not exception-related. In the index.ts file, the NotFoundRoute throws an exception that is caught, so I guess it works on the file's context. How it is not working ? I suppose the router has a thrown exception that would be caught but it is not.

To remind the context, I am trying to force errors to happen to see if the error handling is correct. So in this case I forced

newUser.save()

to fail.

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Express cannot handle thrown exceptions or rejected Promises. To tell express that there is an error you need to call the next() function instead of using throw or rejecting a Promise:

usersRouter.post('/register', async (req: Request, res: Response, next: Function) => {
  try {
    const { email, password } = req.body;
    if (!email || !password)
      res.status(403).send({ message: "Bad Request"});
    const newUser = User.createUser({ email, password });
    await newUser.save();
    res.status(201).send(newUser);
  } catch (err) {

    next(new InternalServerError()); // This is how you "throw" errors
                                     // in Express

  }
})

Note that express only expect you to call the function it passes as the third argument. The name of the argument is up to you. You can use words other than next:

usersRouter.post('/register', async (req: Request, res: Response, error: Function) => {
  try {

    /* some logic */

  } catch (err) {

    error(new InternalServerError());

  }
})

Though traditionally the name of the third argument is next and most javascript developers expect it to be that.

over 4 years ago · Santiago Trujillo Report

0

Adding to slebetman's answer: You can throw errors that will be handled by the exception handler, but only in synchronous middleware. You can try it out:

app.use("/sync", function(req, res) {
  throw "sync";
})
.use("/async", async function(req, res) {
  throw "async";
})
.use(function(err, req, res, next) {
  res.end("Caught " + err);
});
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!