Nút lưu báo lỗi đọc JSON, nhưng đội vận hành lại tìm thấy thay đổi vừa gửi trong hệ thống đích. Ở một ca khác, request trả 200 và cùng đoạn mã đọc JSON vẫn dừng, lần này vì nội dung nhận được là một trang HTML. Hai biểu hiện gần giống nhau ở màn hình có thể cần hai cách xử lý trái ngược: chấp nhận phản hồi không có nội dung theo hợp đồng, hoặc dừng vì nhận sai dạng phản hồi.
Khi API trả 204 hoặc client gặp lỗi parse, đừng bắt đầu bằng việc thêm một cặp ngoặc nhọn vào mọi câu trả lời. Cần chốt hợp đồng phản hồi trước: trạng thái nào dự kiến, có nội dung hay không, dạng nội dung gì và bằng chứng nào cho phép cập nhật trạng thái công việc. Bài này dùng tình huống tổng hợp để đọc các ranh giới đó; không mô tả sự cố đã xảy ra trên một dự án của Onter.
Hai lỗi giống ở màn hình, khác ở hợp đồng
Ví dụ thứ nhất là thao tác cập nhật mà API quy định phản hồi 204 khi hoàn tất. Client vẫn gọi bước đọc JSON cho mọi phản hồi thành công, nên lỗi phát sinh ở bước phân tích nội dung. Ví dụ thứ hai là endpoint dự kiến trả JSON nhưng client nhận HTML. Cả hai đều có thể đi tới cùng một hộp thông báo chung, khiến nhân viên bấm gửi lại mà chưa biết tác động trước đã xảy ra hay chưa.
Muốn điều tra, cần giữ riêng ba kết quả: request đã có phản hồi HTTP, phản hồi có đúng dạng đã thỏa thuận và kết quả nghiệp vụ đã được xác nhận theo hợp đồng. Không dùng một biến success cho cả ba. Việc chia rõ các kết quả này giúp báo đúng lỗi và tránh quyết định gửi lại chỉ dựa vào một ngoại lệ của parser.
Đội sản phẩm cũng cần tham gia lựa chọn câu chữ. “Không đọc được phản hồi” khác “chưa lưu dữ liệu”. Nếu hệ thống chưa biết kết quả, thông báo nên giữ sự chưa biết đó và chỉ người dùng tới cách đối chiếu được hỗ trợ. Không báo hoàn tất khi chưa có bằng chứng; cũng không khẳng định thất bại chỉ vì bước dựng thông báo sau cùng bị lỗi.
API trả 204 thì không có JSON đang chờ ở phía sau
RFC 9110, mục 15.3.5 mô tả 204 là request đã được máy chủ thực hiện thành công và không có nội dung bổ sung gửi trong phản hồi. Phản hồi này kết thúc ở phần header, không mang content hay trailer. Vì vậy một client hợp đồng chấp nhận 204 không nên coi việc thiếu một đối tượng JSON là lỗi dữ liệu đầu ra.
Cách xử lý phù hợp phụ thuộc endpoint. Có thao tác chỉ cần xác nhận đã áp dụng và giữ người dùng ở màn hình hiện tại. Có thao tác cần đọc lại tài nguyên để cập nhật thông tin đang hiển thị. Bước đọc lại, nếu có, phải là một đường đọc được tài liệu API hỗ trợ; đừng suy ra rằng mọi API có một URL GET tương ứng hoặc dữ liệu sẽ lập tức hiện giống nhau ở mọi lớp.
Không sửa phản hồi 204 thành có body chỉ để làm hàm đọc JSON hiện tại bớt báo lỗi. Nếu hợp đồng cần trả một representation, phía cung cấp và phía tiêu thụ phải thống nhất lại trạng thái cùng nội dung phù hợp. Nếu hợp đồng vẫn là không có nội dung, sửa nhánh client để nhận đúng trường hợp đó. Một bên tự đổi sẽ khiến các consumer còn lại đối diện một hợp đồng khác.
Cũng không gộp mọi body rỗng vào 204. Một phản hồi 200 không có phần JSON mà endpoint đã hứa là một ca khác cần điều tra. Giữ mã trạng thái thật trong bằng chứng; đừng tự thay nó bằng mã thuận tiện cho một nhánh xử lý. Chữ “rỗng” mô tả quan sát về dữ liệu, còn 204 mô tả ngữ nghĩa của phản hồi theo giao thức.
Content-Type cho biết dạng được khai báo, chưa xác nhận dữ liệu đúng
Tài liệu Content-Type của MDN giải thích header này mô tả media type của nội dung. Content-Encoding giải quyết cách giải mã encoding, không thay thế media type. Trong điều tra, cần ghi hai lớp riêng thay vì đổi một header nén để thử sửa lỗi cú pháp JSON.
Nếu endpoint đã thỏa thuận JSON mà trả text/html, đó là một dấu hiệu cần xem lại đường request và phản hồi. HTML có thể là nội dung của một lớp trung gian hoặc một trang khác với endpoint dự kiến, nhưng chỉ media type chưa chỉ ra nguyên nhân. Không tự kết luận hết phiên đăng nhập, lỗi proxy hay nhà cung cấp bị hỏng khi chưa có bằng chứng về chặng đã trả lời.
Chiều ngược lại cũng quan trọng: header application/json không khiến các byte bên trong tự trở thành JSON hợp lệ. Cần phân biệt dạng đã khai báo, cú pháp parse được và cấu trúc dữ liệu đáp ứng hợp đồng. Đổi riêng header trên một trang HTML không chuyển nó thành phản hồi API. Bỏ qua header rồi thử parser liên tục cũng che mất một tín hiệu hữu ích cho vận hành.
Việc chọn parser trong một thư viện là hành vi của thư viện, không phải quy luật áp dụng cho mọi client. Với Response.json() của Fetch, phương thức đọc body và phân tích nó như JSON; nếu không phân tích được sẽ có lỗi cú pháp. Đừng hứa phương thức này tự bảo vệ hợp đồng media type thay cho bước kiểm tra do ứng dụng thiết kế.

Đặt ba ca cạnh nhau trước khi viết nhánh xử lý
| Quan sát | Câu hỏi tiếp theo | Không được suy ra |
|---|---|---|
| 204, không có body | Endpoint có cho phép nhánh không nội dung và cần đọc lại gì? | Phải gửi lại vì không nhận đối tượng JSON |
| 200, khai báo text/html | Đúng endpoint và đúng dạng phản hồi hợp đồng chưa? | Chắc chắn do hết phiên đăng nhập |
| 200, khai báo application/json | Parse được và đáp ứng các trường cần thiết chưa? | Mọi giá trị nghiệp vụ bên trong đều đúng |
Bảng này là cách đặt câu hỏi cho một hợp đồng giả định, không phải danh sách mã được chấp nhận cho mọi API. Một endpoint khác có thể trả dạng khác theo tài liệu của nó. Khi bổ sung consumer, nên chuyển các câu hỏi thành ca thử cụ thể cùng người chịu trách nhiệm quyết định, thay vì sao chép một hàm xử lý chung rồi coi mọi khác biệt là ngoại lệ tạm thời.
Với JSON đã parse được, chuyển sang kiểm hợp đồng trường: trường nào bắt buộc, có chấp nhận null không và đơn vị nào được dùng. Đó là phạm vi của bài API đổi kiểu dữ liệu và bảng hợp đồng trường. Bài hiện tại dừng ở ranh giới nhận và đọc representation; nó không thay thế việc duyệt ý nghĩa của payload.
Ngược lại, đừng dùng kiểm schema để che lỗi chưa nhận đúng nội dung. Khi máy chủ gửi một trang HTML, việc báo “thiếu trường amount” dễ khiến người vận hành tìm sai lớp. Thông báo nên chỉ ra bước chưa đạt bằng thuật ngữ đủ rõ, còn log chi tiết giữ trong phạm vi quyền phù hợp. Người dùng cuối không cần nhìn một đoạn stack trace hay trang lỗi nội bộ.
Giữ đủ dấu vết mà không biến log thành kho dữ liệu nhạy cảm
Một biên bản nhỏ có thể ghi operation đã gọi, môi trường, thời điểm, mã trạng thái, media type được khai báo và mã tương quan đã được phép sử dụng. Nếu client đi qua nhiều chặng, cần biết phản hồi được quan sát tại chặng nào. Chỉ lưu dữ liệu thật sự cần cho việc đối chiếu; đừng mặc định xuất toàn bộ request, header xác thực hoặc body vào ticket hỗ trợ.
Để trao đổi giữa các nhóm, tạo mẫu tổng hợp giữ nguyên kiểu lỗi thay cho payload khách hàng. Chẳng hạn một đoạn HTML vô hại cho ca sai dạng, hoặc một JSON nhỏ với trường giả định cho ca parse được. Giữ cả phần mô tả mẫu là tổng hợp để người nhận không hiểu nhầm đó là capture thật. Việc che một trường không đảm bảo những trường còn lại không chứa thông tin riêng.
Nếu cần xem raw body thật trong một môi trường được phép, người có quyền phải kiểm soát cách truy cập và lưu giữ. Bài không yêu cầu lấy cookie, sao chép phiên trình duyệt hay thu thập credential để tái hiện lỗi. Cũng không đổi cấu hình proxy, auth hoặc endpoint production như một bước minh họa. Nhiệm vụ đầu tiên vẫn là xác định hợp đồng và bằng chứng hiện có.
Đừng để lỗi parser tự quyết định gửi lại thao tác ghi
Giả sử tác động ghi đã được áp dụng nhưng màn hình báo lỗi vì nhánh đọc phản hồi không đúng. Gửi lại có thể tạo thêm một tác động nếu API và consumer không có cơ chế phù hợp. Lỗi parse không tự cấp phép retry thao tác ghi. Cần biết request trước đã tạo ra kết quả gì và API hỗ trợ cách đối chiếu nào, theo đúng phạm vi của operation đó.
Điều này không có nghĩa cấm mọi retry. Nó có nghĩa quyết định retry thuộc chính sách của operation, không thuộc một lệnh catch gom chung. Một request đọc, một lệnh cập nhật có khóa kiểm soát và một lệnh tạo đối tượng mới có thể cần ba chính sách khác nhau. Không thêm vòng lặp gửi lại để làm tỷ lệ lỗi giao diện giảm trong khi tác động trùng bị đẩy sang hệ thống đích.
Trong nghiệm thu, cần một ca mà nhánh parser thất bại sau khi đã nhận phản hồi và xác nhận consumer giữ đúng trạng thái đối chiếu. Bài thử chỉ dùng tài nguyên tổng hợp trên môi trường đã cho phép. Nếu chưa có đường đọc kết quả hoặc cơ chế chống trùng được tài liệu hóa, ghi rõ khoảng trống ấy; không bịa rằng hệ thống đã bảo đảm an toàn chỉ vì một hàm trả về false.
Bàn giao hợp đồng phản hồi cùng ca kiểm
Hồ sơ bàn giao nên giữ các trạng thái được chấp nhận, quy định có hay không có nội dung, media type dự kiến và cách báo lỗi ở từng lớp. Kèm các mẫu tổng hợp cho 204, sai media type, JSON sai cú pháp và JSON không đáp ứng cấu trúc. Sau khi sửa, thử cả đường đúng và các nhánh dừng để chắc rằng thông báo không vô tình đảo nghĩa thành công hoặc thất bại.
Đội vận hành cần biết lúc nào được dùng kết quả hiển thị và lúc nào phải đối chiếu thêm. Đội phát triển cần biết nhánh nào nhận lỗi và ai có quyền thay hợp đồng. Khi hai bên cùng đọc được một bộ ca nhỏ, việc sửa connector sẽ có tiêu chí nghiệm thu rõ hơn một yêu cầu chung chung “đừng báo lỗi JSON nữa”.
Nếu cần rà một kết nối đang có phản hồi khó hiểu, hãy chuẩn bị tài liệu endpoint, hợp đồng hiện hành và mẫu tổng hợp đã loại dữ liệu riêng khi Nhận tư vấn & báo giá. Giá: Liên hệ. Phạm vi khởi đầu nên là xác định đúng lớp lỗi và bằng chứng bàn giao, trước khi quyết định sửa client hay đề nghị bên cung cấp thay đổi phản hồi.

