Exception Filters
Trong quá trình coding thì chúng ta sẽ không thể tránh khỏi những trường hợp lỗi không mong muốn và nếu như chúng ta throw ra lỗi đó qua phía client thì có thể dẫn đến lỗi bảo mật hay trải nghiệm người dùng không tốt.
Để khắc phục tình trạng này thì NestJS có một Exception Layer. Layer này sẽ catch tất cả unhandled error và xử lý nó trước khi trả về Controller. Và tất nhiên chúng ta cũng có thể custom response hay handle lại error này trước khi nó được trả về.
Default Response
{
"statusCode": 500,
"message": "Internal server error"
}
Xử lý Error với Exception Filters
Để có thể handle sao cho phù hợp với từng loại Error thì chúng ta có thể Catch những Error mà ta mong muốn
@Catch(HttpException) // Http Error
@Catch(PrismaException) // Database Error
@Catch(CustomErrorInstance) // Custom Error
Sau khi đã Catch được Error mà mình mong muốn thì chúng ta sẽ phải implement lại class ExceptionFilter của NestJS và handle Error.
@Catch()
export class InternalExceptionFilter implements ExceptionFilter {
async catch(exception: HttpException, context: GqlExecutionContext) {
if (exception instanceof HttpException) {
if (exception.getStatus() !== 500) return exception;
}
//Handle Error on production environment
if (process.env.NODE_ENV !== "development") {
const ctx = GqlExecutionContext.create(context).getContext();
const req: Request & { user: Partial<User> | null } = ctx.req;
const { query, operationName, variables } = req.body;
const authorization = {
laboId: req.header("labo-id"),
userId: req.user?.databaseId,
};
const errorParams: ErrorTemplateParams = {
hostname: req.hostname,
query,
payload: JSON.stringify({ operationName, variables }, null, 2),
stack: exception.stack,
errorName: exception.name,
authorization: JSON.stringify(authorization, null, 2),
};
const slack = new SlackService();
slack.sendMessage(errorParams);
// Return default error response
return new InternalServerErrorException("Internal_Error");
}
// return error + stacktrace
return exception;
}
}
Thì ở đây mình đã Catch tất cả Error bao gồm Http Error và Database Error chỉ ngoại trừ những lỗi 4xx đã throw ra.
Ở đây chúng ta có 2 tham số đó làm exception và context thì nó là cái gì?
exception ở đây nó là lỗi nguyên bản nó thuộc về instance của Error. Thì trong exception nó sẽ bao gồm: stacktrace, message, errorName và error.
context này nó được coi là host, chúng ta có thể sử dụng context này để có thể tham chiếu đến Request và Response và có thể custom lại Error chi tiết hơn để có thể tracking bug dễ dàng hơn.
Custom Response
Và cuối cùng để NestJS có thể nhận được Exception Filter này thì t cần phải binding nó vào để có thể sử dụng như một global Filter.
// Handle Internal Error
if (process.env.NODE_ENV !== "development") {
app.useGlobalFilters(new InternalExceptionFilter());
}
Kết bài:
NestJS là framework hỗ trợ mạnh mẽ với nhiều tính năng và Exception Filters là một trong số đó. Thì ở bài này chúng ta đã tìm hiểu qua ExceptionFilter là gì và Handle những Unhandled Error như thế nào.
Hẹn gặp lại mọi người trong bài viết tìm hiểu về NestJS khác.
2 comments
Cho tớ hỏi xíu với bạn ơi
Những catch dưới đây mình sẽ đặt ở những controller mà mình muốn catch exception khi đã set global InternalExceptionFilter phải không nhỉ.
@Catch(HttpException) // Http Error
@Catch(PrismaException) // Database Error
@Catch(CustomErrorInstance) // Custom Error
Zaproxy dolore alias impedit expedita quisquam.