Error Handler với NodeJS
1. Error Handler là gì?
Error Handler là cơ chế giúp ứng dụng phát hiện, tiếp nhận và xử lý lỗi tập trung.
Thay vì mỗi Controller phải tự viết try...catch và trả về lỗi, Express cho phép chuyển tất cả lỗi về một Error Middleware để xử lý thống nhất.
Mục đích:
- Tránh lặp code xử lý lỗi ở nhiều Controller.
- Phân biệt các loại lỗi bằng HTTP Status Code.
- Chuẩn hóa response trả về Client.
- Giúp code dễ bảo trì và debug hơn.
2. Error Handling hoạt động như thế nào?
Trong dự án, cơ chế xử lý lỗi được chia thành 3 phần:
| Thành phần | Nhiệm vụ |
|---|---|
| Custom Error | Định nghĩa các loại lỗi |
| Async Handler | Bắt lỗi từ hàm async |
| Error Middleware | Xử lý lỗi và trả response |
Bước 1: Custom Error – Định nghĩa lỗi
Vấn đề: Nếu sử dụng new Error() thông thường, chúng ta chỉ có thông báo lỗi mà chưa có HTTP Status Code tương ứng.
Giải pháp: Tạo các Custom Error Class kế thừa từ Error để mỗi loại lỗi có sẵn Status Code.
Ví dụ:
class ErrorResponse extends Error {
constructor(message, statusCode) {
super(message)
this.status = statusCode
}
}
class NotFoundError extends ErrorResponse {
constructor(message = 'Not Found') {
super(message, 404)
}
}
Một số loại lỗi thường dùng:
| Error Class | Status | Khi nào sử dụng? |
|---|---|---|
BadRequestError |
400 | Request không hợp lệ |
AuthFailureError |
401 | Xác thực thất bại |
ForbiddenError |
403 | Không có quyền truy cập |
NotFoundError |
404 | Không tìm thấy dữ liệu |
ConflictRequestError |
409 | Dữ liệu bị xung đột |
Ghi nhớ: Custom Error giúp chúng ta chủ động xác định lỗi và Status Code ngay tại nơi phát sinh lỗi.
Bước 2: Async Handler – Bắt lỗi bất đồng bộ
Vấn đề: Controller thường sử dụng async/await để gọi Database hoặc Service. Khi xảy ra lỗi, cần chuyển lỗi đó đến Error Middleware.
Thay vì viết try...catch cho từng Controller, chúng ta tạo một hàm asyncHandler để tái sử dụng.
const asyncHandler = (fn) => {
return (req, res, next) => {
fn(req, res, next).catch(next)
}
}
Cách sử dụng:
router.post(
'/shop/login',
asyncHandler(accessController.login)
)
Cách hoạt động:
asyncHandlernhận một Controller.- Gọi Controller khi có request.
- Nếu Promise bị reject,
.catch(next)sẽ chuyển lỗi cho Express. - Express tiếp tục chuyển lỗi đến Error Middleware.
Ghi nhớ: asyncHandler không trực tiếp xử lý lỗi. Nó chỉ có nhiệm vụ bắt lỗi và chuyển tiếp lỗi.
Bước 3: Error Middleware – Xử lý lỗi tập trung
Sau khi nhận lỗi từ asyncHandler, Express chuyển lỗi đến Error Middleware.
app.use((error, req, res, next) => {
const statusCode = error.status || 500
return res.status(statusCode).json({
status: 'error',
code: statusCode,
message: error.message || 'Internal Server Error'
})
})
Nhiệm vụ:
- Nhận lỗi từ
next(error). - Lấy HTTP Status Code từ lỗi.
- Nếu không có Status Code thì mặc định là 500.
- Trả response JSON thống nhất cho Client.
Lưu ý:
- Error Middleware phải có đủ 4 tham số:
(error, req, res, next). - Phải đặt sau tất cả các Routes để có thể tiếp nhận lỗi từ chúng.
3. Thử hình dung qua một ví dụ thực tế
Giả sử người dùng đăng nhập nhưng nhập sai mật khẩu.
Quá trình xử lý diễn ra như sau:
- Client: Gửi request đăng nhập.
- Router: Gọi Controller thông qua
asyncHandler. - Controller: Gọi
AccessService.signIn(). - Service: Kiểm tra mật khẩu. Nếu sai, ném lỗi:
throw new AuthFailureError('Authentication error')
- Async Handler: Bắt lỗi bằng
.catch(next). - Error Middleware: Nhận lỗi và trả về HTTP 401.
- Client: Nhận response:
{
"status": "error",
"code": 401,
"message": "Authentication error"
}
4. Tổng kết
| Thành phần | Hiểu đơn giản |
|---|---|
| Custom Error | Tạo ra lỗi có thông tin cụ thể và Status Code tương ứng thay vì sử dụng lỗi mặc định |
throw |
Chủ động ném lỗi và dừng luồng chạy hiện tại |
asyncHandler |
Bắt lỗi tự động bắt trọn mọi lỗi được ném ra trong các controller bất đồng bộ mà không cần phải viết try/catch lặp đi lặp lại. |
next(error) |
Chuyển lỗi đến Error Middleware |
| Error Middleware | Xử lý lỗi và trả response |
Luồng xử lý lỗi:

Nguyên tắc: Không cần trả response ở nơi phát sinh lỗi. Hãy để Error Middleware xử lý lỗi.
All rights reserved