Issue
I have an error handler middleware that is supposed to catch any thrown errors and display them in a serialized format.
Error handler middleware
import { NextFunction, Request, Response } from "express";
import { CustomError } from "../errors/custom-error";
export const errorHandler = (err:Error, req:Request, res:Response, next:NextFunction) => {
if(err instanceof CustomError){
return res.status(err.statusCode).send({errors: err.serializeErrors() })
}
res.status(400).send({message: [{message:'Something went wrong'}] })
}
Not-Found-error.ts
export class NotFoundError extends CustomError{
statusCode = 404
constructor(){
super('Not found error')
Object.setPrototypeOf(this, NotFoundError.prototype)
}
serializeErrors(){
return [{ message: 'Not found'}]
}
}
Custom-Error.ts
export abstract class CustomError extends Error{
abstract statusCode: number
constructor(message: string){
super(message)
Object.setPrototypeOf(this, CustomError.prototype)
}
abstract serializeErrors() : {
message: string,
field?: string
}[]
}
index.ts
import express from 'express'
import { errorHandler } from './middleware/error-handler';
import router from './router'
const app = express()
app.use(express.json())
app.use('/api/users', router)
app.use(errorHandler)
const PORT = 8000
app.listen(PORT, () => {
console.log("working on port ",PORT)
})
router.ts
import express from 'express'
import { NotFoundError } from './errors/not-found';
const router = express.Router()
router.all('/*', async (req, res) => {
throw new NotFoundError()
})
export default router
Expected behaviour:
- An incorrect URL is supplied
- A NotFoundError is thrown
- NotFoundError being a subclass of CustomError would have 2 attributes: statusCode and serializeErrors function
- The middleware catches the error and sends back appropriate response
Actual behaviour:
UnhandledPromiseRejectionWarning: Error: Not found error
UnhandledPromiseRejectionWarning: Unhandled promise rejection. This
error originated either by throwing inside of an async function
without a catch block, or by re jecting a promise which was not
handled with .catch(). To terminate the node process on unhandled
promise rejection, use the CLI flag--unhandled-rejections=strict
(see http s://nodejs.org/api/cli.html#cli_unhandled_rejections_mode).
(rejection id: 1)
Any help or suggestion is greatly appreciated.
Solution
You don’t want to throw the error in your handler directly, because express is async code and it will just get swallowed. You need to pass that error through the next function, so that express knows what to do with it.
import express from 'express'
import { NotFoundError } from './errors/not-found';
const router = express.Router()
router.all('/*', async (req, res, next) => {
return next(new NotFoundError());
})
export default router
Answered By – distrill
This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0