ExpressJS: How to throw custom errors
Felipe Leao
Posted on November 2, 2022
The problem
- Throwing readable custom errors is one of the most critical steps in the development of web applications. The communication between services must be clear and straight to the point.
The tool
- Express middlewares when building NodeJS applications
The Solution:
Build an express middleware to throw custom responses error statusCode and messages
Our example will utilize a simple API built with ExpressJS and Prisma as an ORM
// app.ts
import express, { Request, Response, NextFunction } from 'express'
import 'express-async-errors'
import { router } from './routes'
import cors from 'cors'
const app = express()
app.use(express.json())
app.use(cors())
app.use(router)
app.use((err: {err: Error, statusCode: number, message: string}, _req: Request, res: Response, _next: NextFunction) => {
if (err.err && err.err instanceof Error) {
return res.status(err.statusCode).json({
message: err.message,
status: 'error'
})
}
return res.status(500).json({
status: 'error',
message: 'Internal server error'
})
})
export { app }
- In addition, we can also define how our error response will be displayed to our clients. Here you can choose to show whatever you want and whatever you feel is pertinent for the client to see.
// lib/error
const builder = ({ statusCode, message }: {statusCode: number, message: string}) => {
return {
err: new Error(),
statusCode,
message
}
}
export const error = { builder }
- The object error should be thrown in the following manner
// src/services/userService.ts
import { error } from '../../lib/error'
import prismaClient from '../database/client'
import { IUser } from '../types/IUser'
interface ICreateUserRequest {
name: string
email: string
password: string
}
const create = async ({ name, email, password }: ICreateUserRequest): Promise<IUser> => {
if (!email) {
throw error.builder({ statusCode: 422, message: 'Email not provided' })
}
if (await prismaClient.user.findFirst({ where: { email } })) {
throw error.builder({ statusCode: 412, message: 'Email already taken' })
}
const user = await prismaClient.user.create({
data: { name, email, password }
})
return user
}
export const userService = {create}
💖 💪 🙅 🚩
Felipe Leao
Posted on November 2, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.