I'm struggling to handle errors in my NestJS app because I'm writing try/catch everywhere. I'm also not sure whether it's cleaner/best practice to throw errors in a service or in the resolver/controller, or catch it and rethrow it in some interceptor or exception filter. Also is writing code with fn().then().catch()
cleaner since I seem to be rewriting the same errors a lot when using try/catch.
Here is an example of my code with poor error handling with lots of boilerplate code.
How would you handle the errors more cleanly and DRY?
async validateUser(
email: string,
plainTextPassword: string,
): Promise<User | null> {
try {
const user = await this.usersRepository.findOne({ email });
if (!user) {
throw new HttpException(
"Wrong credentials provided",
HttpStatus.BAD_REQUEST,
);
}
const isMatch = await this.verifyPassword(
plainTextPassword,
user?.password,
);
if (isMatch) {
await this.usersRepository.filter(user);
return user;
}
} catch (err) {
this.logger.error(err);
throw new HttpException(
"Something went wrong",
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
/** This function is used by the validateUser function
* Note: This could be written much much shorter in 1-2 lines...
*/
async verifyPassword(plainTextPassword: string, hashedPassword: string) {
try {
const isMatch = await bcrypt.compare(plainTextPassword, hashedPassword);
if (!isMatch) {
throw new HttpException(
"Wrong credentials provided",
HttpStatus.BAD_REQUEST,
);
}
return isMatch;
} catch (err) {
this.logger.error(err);
throw new HttpException(
"Something went wrong",
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
Here are some suggestions:
HttpException
, such as NotFoundException
, ForbiddenException
and InternalServerErrorException
. See this.InternalServerErrorException
s, since NestJS's default filter will handle any uncaught error and throw the 500 himself.