Nguyên tắc: một định dạng lỗi duy nhất cho toàn API, máy đọc được và người debug được. RFC 9457 chuẩn hoá đúng việc đó với Content-Type: application/problem+json.
Các field chuẩn:
- type — URI định danh loại lỗi (client so khớp field này, không so khớp chuỗi title).
- title — mô tả ngắn, cố định cho mỗi type.
- status — mã HTTP, lặp lại cho tiện log.
- detail — mô tả cho lần lỗi cụ thể này.
- instance — URI của lần xảy ra lỗi.
- Được phép thêm extension member tuỳ ý (errors, trace_id, balance...).
json
HTTP/1.1 403 Forbidden
Content-Type: application/problem+json
{
"type": "https://api.example.com/errors/insufficient-funds",
"title": "Insufficient funds",
"status": 403,
"detail": "Balance is 30000 VND, required 120000 VND",
"instance": "/accounts/12/transfers/9a1",
"trace_id": "01J8Z...",
"balance": 30000
}Hai lỗi thiết kế hay gặp:
- trả message tiếng người thay đổi liên tục rồi client đi
if (msg.includes(...)); - rò rỉ stack trace hoặc câu SQL vào
detail
Mã lỗi ổn định để client xử lý, trace_id để dev tra log — đó là hai thứ thực sự cần.