I set up an error handler middleware in my backend to handle errors (duh) but it seems to not be doing what it's supposed to. As in every time there is an error, the app crashes and there's no proper response from the server. The way I understand it is that I am throwing a new error through my authController.js but I am never handling the exception made in server.js through errorHandlerMiddleware, therefore crashing the server. Can anyone explain to me what I am doing wrong? Thanks
Error Handler
const errorHandlerMiddleware = (err, req, res, next)=>{
console.log(err)
const defaultError = {
statusCode: err.statusCode || 500,
msg: err.message || "Something Went Wrong, Try Again Later",
}
if(err.name==="ValidationError"){
defaultError.statusCode = 400
defaultError.msg = Object.values(err.errors).map((item)=> item.message).join(', ')
}
if(err.code && err.code === 11000){
defaultError.statusCode = 400
defaultError.msg= `${Object.keys(err.keyValue)} has to be unique`
}
res.status(defaultError.statusCode).json({msg: defaultError.msg})
}
export default errorHandlerMiddleware
Server
import express from "express";
const app = express();
dotenv.config();
import notFound from "./middleware/NotFound.js";
import errorHandlerMiddleware from "./middleware/errorHandlerMiddleware.js";
import authRouter from "./routes/authRouter.js";
import dotenv from "dotenv";
import connectDB from "./db/connect.js";
app.use(express.json());
app.get("/", (req, res) => {
res.send("Welcome");
});
app.get("/api/v1", (req, res) => {
res.json({ msg: "API" });
});
app.use("/api/v1/auth", authRouter);
app.use(notFound);
app.use(errorHandlerMiddleware);
const port = process.env.PORT || 5000;
const start = async () => {
try {
await connectDB(process.env.MONGO_URL);
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
} catch (error) {
console.log(error);
}
};
start();
Auth Controller
import {BadRequestError, UnauthenticatedError} from "../errorPackage/index.js"
import User from '../models/User.js'
const register = async(req, res) =>{
const {name, email, password} = req.body
if(!name || !email || !password){
throw new BadRequestError("Please Provide All Values")
}
const alreadyUser = await User.findOne({email})
if(alreadyUser){
throw new BadRequestError("Email In Use")
}
const user = await User.create(req.body)
const token = user.createJWT()
res.json({
user:{
name: user.name,
email: user.email,
},
token,
})
console.log('register')
}
const login = async(req, res) =>{
const{email, password} = req.body
if(!email || !password){
throw new BadRequestError("Please Provide All Values")
}
const user = await User.findOne({email}).select('+password')
if(!user){
throw new UnauthenticatedError("Invalid Email")
}
const passwordMatch = await user.comparePassword(password)
if(!passwordMatch){
throw new UnauthenticatedError("Invalid Credentials")
}
const token = await user.createJWT()
user.password = undefined;
res.status(200).json({user, token})
console.log('login success')
}
const updateUser = async(req, res) =>{
res.send('Update')
}
export {register, login, updateUser}
authRouter
import express from "express";
const router = express.Router()
import { register, login, updateUser} from "../controllers/authController.js";
router.route('/register').post(register)
router.route('/login').post(login)
router.route('/updateUser').patch(updateUser)
export default router
An example of an error would be sending a post request through register with an already in-use email, it would look something like this
[0] Server is running on port 5000
[0] file:///C:/Users/Bharat/Desktop/MERNPrj/controllers/authController.js:10
[0] throw new BadRequestError("Email In Use")
[0] ^
[0]
[0] BadRequestError: Email In Use
[0] at register (file:///C:/Users/Bharat/Desktop/MERNPrj/controllers/authController.js:10:15)
[0] at processTicksAndRejections (node:internal/process/task_queues:96:5) {
[0] statusCode: 400
[0] }
[0] [nodemon] app crashed - waiting for file changes before starting...
What I can surmise from this is that the app is crashing before the server has a chance to respond with the proper error reponse
authRouterfor example) but OTOH, this is by far a minimal reproducible example.