I'm trying to create a global error handler in node js with typescript. I have created some custom classes which extends error class something like this:-
custom class
export abstract class CustomError extends Error {
abstract statusCode: number;
abstract errorMessage: string;
abstract data: unknown;
constructor() {
super();
Object.setPrototypeOf(this, CustomError.prototype);
}
abstract serializeError(): { message: string; fields?: string }[] | string;
}
Bad request error class
import { StatusCodes } from 'http-status-codes';
import { CustomError } from './custom.error';
class BadRequestException extends CustomError {
statusCode = StatusCodes.BAD_REQUEST;
errorMessage: string;
data: any;
constructor(errorMessage?: string) {
super();
// set default value
this.errorMessage = errorMessage || 'Bad Request';
Object.setPrototypeOf(this, BadRequestException.prototype);
}
serializeError() {
return this.errorMessage;
}
}
export default BadRequestException;
server.js
dotenv.config();
const app: Express = express();
app.use('/', routes);
app.use(globalErrorHandler);
export default app;
routes.ts
import express from 'express';
import UserController from '../controller/user/user-controller';
import NotFoundException from '../exception/not-found-exception';
import authorizationMiddleware from '../middleware/authorization-middleware';
const router = express.Router();
// users routes
router.post('/user/create', UserController.createUser);
router.get('/user/profile/:key', UserController.getProfile);
router.get('/user/directus', UserController.getDirectUs);
router.use('*', () => {
throw new NotFoundException();
});
export default router;
controller.ts
import { Request, Response } from 'express';
import { StatusCodes } from 'http-status-codes';
import { directus } from '../../config/directus-confgi';
import BadRequestException from '../../exception/bad-request-exception';
import { USER } from '../../interface/user-interface';
import UserService from './user.service';
class UserController {
// getting user profile
static async getDirectUs(request: Request, response: Response) {
try {
const user = await directus.items('articles').readOne(15);
response.status(StatusCodes.OK).json({ user });
} catch (error: any) {
throw new BadRequestException(error.message);
}
}
}
export default UserController;
Global Error Handler
import { StatusCodes } from 'http-status-codes';
import { Request, Response, NextFunction } from 'express';
import { CustomError } from '../exception/custom.error';
const globalErrorHandler = (err: any, req: Request, res: Response,next:NextFunction) => {
if (err instanceof CustomError) {
const error: { message: string; errors?: any } = {
message: err.errorMessage ? req.body.i18nObj.__(err.errorMessage) : '',
};
if (err.data) error.errors = err.serializeError();
return res.status(err.statusCode).json(error);
}
res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
message: err.message
? err.message
: req.body.i18nObj.__('MESSAGES.UNABLE_COMPLETE_REQUEST'),
error: { message: err.message, err },
});
};
export default globalErrorHandler;
I'm getting errors in my controller catch block and bad-request error class but after that my global error handler middleware function is not able to get this error, in a result, I'm not able to send this error as a response.
I don't know what I'm doing wrong or how can call my middleware function without throwing an actual error from the controller I want to use my custom error class to formate error and status code.