- Nhà phát triển
- Lỗi và cách xử lý
Lỗi và cách xử lý
Khi một lệnh gọi API không thành công, hệ thống phản hồi qua mã trạng thái HTTP chuẩn kèm theo thông tin lỗi nghiệp vụ chi tiết. Trang này cung cấp bảng mã lỗi thực tế đối tác gặp phải, cách phân loại ba dạng phản hồi lỗi, và quy tắc xác định lỗi nào được phép gọi lại.
Ba dạng lỗi tồn tại song song
Phần tiêu đề “Ba dạng lỗi tồn tại song song”Bộ xử lý lỗi của hệ thống quyết định cấu trúc dữ liệu trả về dựa trên nguồn gốc phát sinh lỗi. Đối tác cần hỗ trợ cả ba dạng phản hồi này trong bộ phân tích lỗi của mình:
| Dạng | Mã HTTP | Cách nhận biết |
|---|---|---|
| Lỗi HTTP thông thường | Giữ nguyên mã của thao tác (401, 403, 404…) | Có mốc thời gian và đường dẫn gọi API, không có mã lỗi sáu chữ số |
| Lỗi nghiệp vụ từ tầng xử lý | Luôn trả về 422 | Có mã lỗi sáu chữ số trong danh sách lỗi trả về |
| Lỗi ngoài dự kiến | Luôn trả về 500 | Thông điệp lỗi chung, chỉ có mốc thời gian và đường dẫn |
Sơ đồ dưới đây cho thấy cách phân loại ba dạng phản hồi lỗi từ API:
flowchart LR A["Một lệnh gọi bị lỗi"] --> B["Dạng 1 — Lỗi HTTP thông thường"] A --> C["Dạng 2 — Lỗi nghiệp vụ từ dịch vụ"] A --> D["Dạng 3 — Lỗi ngoài dự kiến"] B --> B1["Có thời gian và đường dẫn, không có mã 6 chữ số"] C --> C1["Luôn 422, có mã 6 chữ số trong danh sách lỗi"] D --> D1["Luôn 500, thông điệp hệ thống chung"] B1 --> X["Bộ phân tích lỗi của bạn cần xử lý cả 3 dạng"] C1 --> X D1 --> XCách xây dựng bộ phân tích an toàn: đọc mã HTTP trước, sau đó thử đọc mã lỗi sáu chữ số, và luôn chuẩn bị cho trường hợp mã lỗi không xuất hiện. Không giả định mọi phản hồi lỗi đều có cùng một cấu trúc.
Bẫy mất mã lỗi
Phần tiêu đề “Bẫy mất mã lỗi”Trong một số trường hợp khi lỗi nghiệp vụ bị bao bọc lại ở tầng chuyển tiếp HTTP 422, danh sách lỗi trả về có thể rỗng. Đối tác nhận phản hồi 422 nhưng không kèm mã lỗi sáu chữ số nào, chỉ có mã trạng thái, mốc thời gian và đường dẫn yêu cầu.
Quy tắc xử lý bắt buộc:
- Không giả định mọi phản hồi 422 đều có mã lỗi. Bộ xử lý phải an toàn khi danh sách lỗi rỗng.
- Gặp phản hồi 422 không có mã lỗi thì không gọi lại ngay; ghi log kèm mã truy vết (trace ID) và liên hệ Ferry để kiểm tra.
- Trong nhật ký ứng dụng, luôn ghi lại cả mã HTTP lẫn mã lỗi sáu chữ số để thuận tiện đối chiếu.
Lỗi kiểm tra dữ liệu trả 422, không phải 400
Phần tiêu đề “Lỗi kiểm tra dữ liệu trả 422, không phải 400”Hệ thống Ferry cấu hình lỗi kiểm tra dữ liệu đầu vào (validation) trả về mã 422 thay vì 400 thông thường:
- Cấu trúc danh sách lỗi là đối tượng phẳng theo tên trường, không phải mảng. Mỗi khoá là tên trường vi phạm, giá trị là nội dung ràng buộc bị vi phạm. Với các trường lồng nhau, đối tượng được lồng tương ứng.
- Trường dữ liệu thừa bị loại bỏ im lặng: Nếu bạn gửi lên các trường không nằm trong hợp đồng dữ liệu, hệ thống tự động loại bỏ mà không sinh lỗi cảnh báo.
Bảng mã trạng thái HTTP
Phần tiêu đề “Bảng mã trạng thái HTTP”Sáu mã trạng thái HTTP mà đối tác thực sự gặp trong quá trình tích hợp:
| Mã | Ý nghĩa thực tế | Có nên gọi lại không? |
|---|---|---|
| 401 | Khoá API thiếu, sai định dạng, sai secret hoặc đã bị thu hồi | Không — dừng vòng lặp, kiểm tra lại cấu hình khoá |
| 403 | Thiếu quyền truy cập hoặc hệ thống phân quyền gặp sự cố | Thử lại đúng một lần; nếu vẫn lỗi thì liên hệ Ferry |
| 422 | Dữ liệu không hợp lệ hoặc phát sinh lỗi nghiệp vụ | Không, trừ mã báo đang có tiến trình xuất vé khác |
| 429 | Vượt giới hạn tốc độ gọi API | Có, thực hiện theo hướng dẫn tại trang Giới hạn |
| 500 | Lỗi máy chủ ngoài dự kiến từ hệ thống Ferry | Có, thử lại với khoảng lùi tăng dần |
| 200 kèm mảng rỗng | Có thể là lỗi hệ thống im lặng chứ không phải hết dữ liệu | Không gọi lại ngay — xem chi tiết mục lỗi im lặng |
Sơ đồ dưới đây cho thấy cây quyết định xử lý theo mã trạng thái HTTP:
flowchart TD A["Nhận phản hồi lỗi từ API"] --> B{"Mã trạng thái HTTP là gì?"} B -->|401| C["Khoá thiếu, sai hoặc bị thu hồi"] B -->|403| D["Thiếu quyền hoặc hệ thống phân quyền lỗi"] B -->|422| E["Dữ liệu sai hoặc lỗi nghiệp vụ"] B -->|429| F["Vượt giới hạn tần suất gọi"] B -->|500| G["Lỗi ngoài dự kiến phía Ferry"] C --> C1["Không gọi lại — kiểm tra khoá rồi dừng"] D --> D1["Gọi lại 1 lần, nếu vẫn lỗi báo Ferry"] E --> E1["Không gọi lại, trừ trường hợp tiến trình đang chạy"] F --> F1["Gọi lại theo khoảng lùi tăng dần"] G --> G1["Gọi lại có khoảng lùi tăng dần ngẫu nhiên"]Nhóm Zalo ZNS luôn trả 403
Phần tiêu đề “Nhóm Zalo ZNS luôn trả 403”Các route gửi thông báo Zalo ZNS hiện tại chưa được cấp quyền cho khoá API đối tác. Kết quả là mọi lệnh gọi tới nhóm này đều trả về 403, ngay cả khi khoá API của bạn hoàn toàn hợp lệ và có đầy đủ quyền khác. Bạn không nên thiết kế nghiệp vụ tự động gọi nhóm này qua khoá API.
Bảng mã lỗi đối tác thực sự gặp
Phần tiêu đề “Bảng mã lỗi đối tác thực sự gặp”Bên cạnh mã trạng thái HTTP, các lỗi nghiệp vụ (thường đi kèm mã HTTP 422) mang mã lỗi sáu chữ số để chỉ rõ nguyên nhân cụ thể:
| Mã lỗi | Nhóm nghiệp vụ | Ý nghĩa thực tế | Cách xử lý | Được gọi lại? |
|---|---|---|---|---|
110101 | Hãng tàu | Đăng nhập vào cổng hãng thất bại | Chờ rồi thử lại với khoảng lùi tăng dần; báo Ferry nếu kéo dài | Có |
110102 | Hãng tàu | Lỗi phiên xác thực phía hãng tàu | Chờ tác vụ nền của Ferry tự khôi phục phiên rồi gọi lại | Có |
110295 | Hãng tàu | Chuyến tàu tại hãng đã hết chỗ hoặc bị khoá | Thông báo cho khách chọn chuyến hoặc khoang ghế khác | Không |
120100 | Đặt vé | Đang có tiến trình xuất vé khác cho cùng booking | Chờ ít nhất 60 giây để khoá xuất vé nhả ra | Có |
120101 | Đặt vé | Số dư ví khách hàng không đủ để thanh toán | Yêu cầu khách hàng nạp thêm tiền vào ví | Không |
120105 | Đặt vé | Dữ liệu booking không hợp lệ (sai định dạng vé/khách) | Kiểm tra thông tin hành khách, định dạng giấy tờ và sửa dữ liệu | Không |
120110 | Đặt vé | Trạng thái booking không cho phép thao tác | Tra cứu lại trạng thái booking trước khi thực hiện bước tiếp | Không |
120120 | Đặt vé | Số dư tài khoản tổ chức không đủ để đặt vé | Nạp tiền vào tài khoản tổ chức đại lý | Không |
120205 | Đặt vé | Số dư ở mức booking không đủ để trừ thanh toán | Tổ chức sở hữu booking cần kiểm tra và nạp tiền | Không |
130205 | Khách hàng | Số dư tài khoản khách hàng không đủ | Khách hàng cần nạp thêm số dư | Không |
130206 | Khách hàng | Số tiền giữ chỗ của khách không đủ | Kiểm tra hạn mức giữ chỗ và số dư tài khoản khách | Không |
140201 | Tổ chức | Dữ liệu đầu vào của thao tác số dư không hợp lệ | Kiểm tra và sửa dữ liệu giao dịch | Không |
140101 | Tổ chức | Số dư tổ chức không đủ | Kiểm tra và nạp đủ số dư tổ chức | Không |
150105 | Đơn hàng | Trùng số giấy tờ tuỳ thân của hành khách | Kiểm tra và sửa thông tin hành khách bị trùng | Không |
150102 | Đơn hàng | Trạng thái đơn hàng không hợp lệ cho thao tác | Tra cứu trạng thái đơn hàng để xác nhận | Không |
160105 | Huỷ vé | Không đủ số dư để trả phí tạo yêu cầu huỷ vé | Nạp tiền vào tài khoản tổ chức rồi tạo lại yêu cầu | Không |
160110 | Huỷ vé | Thiếu ngày hoặc giờ khởi hành nên không tạo được yêu cầu huỷ | Gửi mã chuyến và mã truy vết cho Ferry kiểm tra | Không |
220000 | Thông báo | Lỗi gửi thông báo chưa xác định nguyên nhân | Ghi mã truy vết và ngữ cảnh lệnh gọi; liên hệ Ferry | Không tự động |
220105 | Thông báo | Dữ liệu gửi thông báo không hợp lệ (va chạm mã) | Kiểm tra ngữ cảnh: mẫu email booking hay email yêu cầu huỷ | Không |
220110 | Thông báo | Trạng thái không hợp lệ để gửi thông báo | Kiểm tra trạng thái booking hoặc yêu cầu huỷ trước khi gửi | Không |
Hai chữ số đầu xác định dải nghiệp vụ. Danh mục dải gồm:
| Dải | Nhóm | Phạm vi đối tác |
|---|---|---|
11xxxx | Hãng tàu | Có, khi xuất vé |
12xxxx | Đặt vé | Có, khi tạo và xác nhận booking |
13xxxx | Khách hàng | Có, dữ liệu và số dư |
14xxxx | Tổ chức | Có, tổ chức con và hạn mức |
15xxxx | Đơn hàng | Có, tính giá và huỷ đơn |
16xxxx | Huỷ vé | Có, yêu cầu huỷ |
19xxxx | Theo dõi vé | Không có route đối tác |
21xxxx | Hoá đơn | Nhóm route bị khoá |
22xxxx | Thông báo | Có, thông báo booking |
80xxxx | Ngân hàng | Ngân hàng gọi vào, không phải đối tác |
90xxxx | Phân quyền | Không nhận mã này; phản hồi là 403 |
91xxxx | Sổ nội bộ | Không thuộc nghiệp vụ đối tác |
Với 120100, chờ ít nhất 60 giây không có nghĩa khoá đã nhả: khoá xuất vé có thời hạn 600 giây, khoá thanh toán 180 giây. Xác nhận còn có giới hạn mềm 5 lần trong 60 giây theo booking; đây là lỗi nghiệp vụ, không phải giới hạn HTTP 429. Tiếp tục đọc trạng thái thay vì gửi dồn lệnh xác nhận.
Ba chỗ mã lỗi gây nhầm
Phần tiêu đề “Ba chỗ mã lỗi gây nhầm”Va chạm mã ở dải 22xxxx
Phần tiêu đề “Va chạm mã ở dải 22xxxx”Ba mã lỗi trong dải gửi thông báo được dùng chung giữa nhóm thông báo booking và nhóm thông báo yêu cầu huỷ vé:
220000: Lỗi không xác định220105: Dữ liệu đầu vào không hợp lệ220110: Trạng thái không hợp lệ
Khi nhận mã 220105, bạn không thể suy ra lỗi thuộc nhóm booking hay nhóm huỷ vé nếu chỉ dựa vào mã số; cần đối chiếu ngữ cảnh của lệnh gọi API vừa thực hiện.
Các mã “số dư không đủ” khác nhau
Phần tiêu đề “Các mã “số dư không đủ” khác nhau”Nhiều mã lỗi cùng thông báo không đủ tiền nhưng đối tượng cần nạp tiền hoàn toàn khác nhau:
| Mã lỗi | Ý nghĩa | Đối tượng cần nạp tiền |
|---|---|---|
120205 | Số dư ở mức booking không đủ để trừ tiền | Tổ chức sở hữu booking |
130205 | Số dư khách hàng không đủ | Khách hàng cụ thể đó |
160105 | Không đủ số dư để tạo yêu cầu huỷ vé | Tổ chức tạo yêu cầu huỷ vé |
120101 | Số dư khách hàng không đủ ở bước đặt vé | Khách hàng |
120120 | Số dư tổ chức không đủ ở bước đặt vé | Tổ chức đại lý |
130206 | Số tiền giữ chỗ không đủ | Khách hàng |
Lưu ý: mã 160105 trả về dưới dạng đối tượng chứa mã và thông điệp, không phải số trần. Tất cả các mã thiếu số dư đều không được tự động thử lại vì số dư không thể tự tăng lên nếu chưa nạp tiền.
Cơ chế gán nhãn mã lỗi chỉ đăng ký sáu nhóm
Phần tiêu đề “Cơ chế gán nhãn mã lỗi chỉ đăng ký sáu nhóm”Bộ gán nhãn mô tả mặc định của hệ thống chỉ bao gồm 6 nhóm (chủ yếu là booking và hãng tàu). Các mã nằm ngoài 6 nhóm này thường trả về nhãn “không xác định”. Do đó, ứng dụng phía bạn nên phân loại lỗi dựa trên con số mã lỗi chính xác thay vì phụ thuộc vào chuỗi nhãn chữ đi kèm.
Lỗi im lặng
Phần tiêu đề “Lỗi im lặng”Nhóm lỗi cần đặc biệt lưu ý vì không trả về mã 4xx hoặc 5xx:
- Mảng rỗng thay cho lỗi hệ thống: Các API liệt kê dữ liệu khi gặp lỗi máy chủ hoặc lỗi phân quyền nội bộ có thể được xử lý nuốt lỗi và trả về HTTP 200 kèm danh sách rỗng
[]thay vì trả về mã 500. - Con trỏ phân trang hỏng tự quay về trang đầu: Nếu chuỗi con trỏ phân trang bị lỗi hoặc giải mã thất bại, hệ thống tự động quay về trang đầu tiên mà không báo lỗi.
- Tham số sắp xếp sai bị thay thế: Chỉ tham số sắp xếp hợp lệ mới có tác dụng; các trường không hợp lệ bị tự động chuyển về sắp xếp mặc định theo
_id.
Quy tắc phòng vệ:
- Đặt ngưỡng cảnh báo cho các truy vấn vốn luôn có dữ liệu: nếu bỗng nhiên trả về rỗng, hãy nghi ngờ có lỗi hệ thống chứ không vội kết luận là hết dữ liệu.
- Không dùng kết quả rỗng làm căn cứ để tự động xoá hoặc huỷ dữ liệu phía bạn.
- Ghi log con trỏ phân trang để phát hiện nếu xảy ra vòng lặp quay về trang đầu.
Sai lầm thường gặp
Phần tiêu đề “Sai lầm thường gặp”| Hiểu nhầm | Thực tế | Hệ quả |
|---|---|---|
| Mọi phản hồi 422 đều có mã lỗi | Có trường hợp danh sách lỗi bị rỗng | Bộ phân tích lỗi bị văng ngoại lệ khi đọc dữ liệu rỗng |
| Danh sách lỗi 422 luôn là một mảng | Là đối tượng phẳng ánh xạ theo tên trường | Hàm duyệt mảng đọc ra rỗng và bỏ sót lỗi dữ liệu |
| Dữ liệu sai thì API trả về 400 | Hệ thống Ferry trả về 422 | Nhánh bắt mã 400 không bao giờ chạy |
| Nhận 403 nghĩa là khoá bị thu hồi | Có thể hệ thống phân quyền đang gặp sự cố | Tự ý ngắt tích hợp trong khi lỗi nằm ở phía máy chủ |
| Danh sách rỗng nghĩa là không có dữ liệu | Có thể do lỗi máy chủ bị xử lý trả về rỗng | Xoá hoặc cập nhật sai trạng thái dữ liệu phía đối tác |
| Thiếu số dư thì chờ rồi gọi lại | Số dư không tự tăng lên | Lặp vô ích và gây trễ xử lý đơn hàng |
Tra ở đâu trên Scalar
Phần tiêu đề “Tra ở đâu trên Scalar”Mô tả chi tiết và các trường dữ liệu của từng mã lỗi có thể tra cứu theo nhóm tương ứng trên https://api.ferry.vn/docs:
| Mục tiêu tra cứu | Nhóm trên giao diện API |
|---|---|
| Mã lỗi khi tạo đơn và xác nhận xuất vé | Bookings |
| Mã lỗi phía hãng tàu và lỗi phiên đăng nhập | Operator |
| Mã lỗi khi tính lại giá và huỷ đơn | Order |
| Mã lỗi số dư và hạn mức của tổ chức | Organizations |
| Mã lỗi số dư và thông tin khách hàng | Customers |
| Mã lỗi gửi thông báo booking | Booking mailer |
| Lệnh đọc dùng để kiểm tra khi nghi ngờ lỗi phân quyền | Voyage |
Đọc tiếp
Phần tiêu đề “Đọc tiếp”| Trang | Đọc khi nào |
|---|---|
| Quy ước chung | Hiểu chi tiết về phân trang, con trỏ và định dạng dữ liệu |
| Xác thực | Xử lý lỗi 401 và quy trình quản trị khoá API |
| Giới hạn | Xử lý mã 429 và phân biệt giới hạn IP với giới hạn booking |
| Đặt vé: vòng đời một booking | Hiểu ngữ cảnh phát sinh mã 120100 và các mã số dư |
| Tiền: số dư, hạn mức và công nợ | Hướng dẫn nạp tiền để xử lý nhóm lỗi số dư không đủ |
| Xuất vé và đơn hàng | Xử lý các tình huống lỗi khi xuất vé với hãng tàu |
| Huỷ vé và hoàn tiền | Chi tiết quy trình và mã lỗi dải 16xxxx |
| Trước khi chạy thật | Danh mục kiểm tra toàn diện trước khi mở hệ thống chạy thật |
Điểm chưa xác định
Phần tiêu đề “Điểm chưa xác định”| Nội dung | Tình trạng |
|---|---|
| Nhóm Zalo ZNS luôn trả 403 có được mở cho khoá API không | Đang chờ quyết định cấu hình phân quyền từ phía quản trị hệ thống. |
| Trường hợp lỗi 422 bị mất mã lỗi | Hiện chưa có lịch trình cập nhật chuẩn hoá; đối tác cần duy trì lớp kiểm tra an toàn khi danh sách lỗi rỗng. |
| Mở rộng nhãn mô tả cho các dải mã lỗi ngoài 6 nhóm | Chưa có kế hoạch bổ sung; khuyến nghị dựa trên mã số thay vì nhãn chữ. |