5 phút đọcCập nhật

Mười lỗi debug JSON làm đội tiêu phí giờ (và cách vá nhanh)

Tác giả: Biên tập Safe Local Tools

JSON hay hỏng không phải vì ngẫu nhiên. Hầu hết chỉ có vài chủ đề tái hiện: cú phép, Unicode, các giá trị JavaScript không hợp lệ trong JSON và mô hình tay-hai chỉnh sửa bằng app chat.

Đặc biệt hữu ích khi một API báo Unexpected token và bạn chỉ được nhìn bản được format lại: Safe Local Tools xử lý cục bộ để bạn không ném token hay bí mật lên các máy chủ định dạng công khai.

OG illustration

Khác nhau căn bản: JSON không phải object literal của JavaScript

JSON chỉ có chuỗi với ngoặc kép đôi, không có định dạng số bằng tiền tố như kiểu 0128 kiểu bát phân của một số công cụ cũ, đúng từ khóa true/false/null, và không được phép có dấu phẩy sau phần tử cuối. Literal JavaScript chấp nhận dấu phẩy thừa, ghi chú, undefined, NaN và vô cực—tất cả đều nằm ngoài RFC 8259.

Sai lầm “quy trình” là chia sẻ “JSON” qua app chat và trình duyệt tự sửa dấu nháy kiểu thông minh thành dấu vô hại cho mắt người nhưng không hợp lệ cho parser.

Lỗi 1 và 2: dấu phẩy thừa và nháy đơn

Kiểu mẫu { "a": 1, } vẫn rất hay gặp; loại trailing comma và mọi thứ ổn. Nếu không tự chỉnh, hãy bắt JSON.parse trong CI cho mọi fixture xuất từ template.

Lỗi thứ hai là bọc khóa bằng nháy đơn—đó chỉ được phép trong JS, không phải trong JSON.

Lỗi 3 và 4: ký tự điều khiển và NaN/Infinite/undefined

Chuỗi không được chứa xuống dòng nguyên bản—phải \n hoặc tách chiến lược. Quan sát lỗi “bad control character” trỏ giữa chuỗi dài: triệu chứng kinh điển khi nhúng prose hoặc log giao tay.

JSON không chứa NaN hay Infinity. undefined bị stringify bỏ hoặc ném lệch tùy runtime.

Lỗi 5: khóa trùng không xác định hành vi

Hai khóa retry có thể thắng cái sau hoặc cái trước tùy trình đọc,

không phân biệt thì logic downstream không thể chứng minh tính xác định. Lint schema và báo như bug nếu lặp khóa trong cấu hình.

Lỗi 6: comment không thuộc JSON thuần

JSONC chỉ nên được phép ở nơi công cụ rõ ràng hỗ trợ,

chứ không nên ép file có /* được commit với đuôi .json rồi thắc mắc vì production fail.

Lỗi 7 và 10: BOM, encoding, và dán bí mật

UTF-8 BOM thôi cũng khiến parser vấp cửa trong khi mắt người thấy bình thường,

các xuất từ Excel hay hệ Legacy hay gặp—normalize trước khi ingest.

Lỗi lớn về đạo đức và tuân thủ là làm đẹp một object chứa client secret và dán vào Slack. Khi chỉnh cấu hình chứa bí mật, chỉ được phép các bước cục bộ.

Quy trình chặt để không kẹt vòng chỉnh sửa mù

Một là lấy đúng byte lỗi. Hai là gắn pretty-print cục bộ. Ba là tái căn chỉ normalization (UTF-8, strip BOM). Bốn là parse lặp và ghi chỗ lỗi. Năm là so version schema trước khi ép buộc cấu trúc.

Phía sau lỗi parse: quan hệ với OpenAPI, GraphQL và luồng streaming

JSON không chỉ là tệp tĩnh: nhiều service trả chunked transfer hoặc server-sent frames; một frame lỗi vẫn là một chuỗi text khiến JSON.parse ném trong khi bạn chỉ có hai trăm kilobyte đầu của phản hồi trong buffer debugger. Kiểu sự cố này dễ bị nhầm với lỗi mạng, nhưng bản chất là cú pháp—và chỉ vào các byte được ghi vào một lần bạn nhìn được cấu trúc được phục chế không hoàn chỉnh.

Khi có OpenAPI hay JSON Schema trong CI, một bài kiểm tra parse chưa đủ: schema giúp bạn thấy biến kiểu (string thay vì number) trước khi vận hành quyết định sao chép dữ liệu qua vùng không an toàn. Với GraphQL, phản hồi lồng nhiều lớp dễ che vết thương lồng bên trong error.extensions khi client chỉ log message tầng ngoài.

Một thói quen hữu ích là lưu “payload thô” sau khi strip token sang placeholder tĩnh; vừa giúp tái hiện bug mà không lộ bí mật, vừa cho phép bạn chạy lại parser trên cùng byte khi nâng thư viện. Trong các buổi postmortem, ràng buộc “thảo luận trên một bản redact duy nhất” tránh các cuộc trao đổi song song không đồng bộ và khiến team hiểu cùng một hàng log.

Tổng kết chiến lược khi không phải dòng nhật ký nào cũng là một gói JSON hoàn chỉnh

Một pipeline observability không bao giờ nhận 100 phần trăm event hợp lệ: client crash giữa hai packet, exporter gửi một dòng không phải JSON xen kẽ các dòng có. Chuẩn hoá chỗ ingestion (ví dụ coi các dòng parser fail như một kênh riêng) giúp bạn không bẻ cong RFC để các công cụ format online “cầu được cầu thấy”.

Tiêu điểm triết lý: bao giờ cũng tách chỗ chứng minh cú pháp với chỗ chứng minh nội dung ngữ nghĩa—đó là một lý do các team lớn tách hai bước validation. Safe Local Tools chỉ là bước đầu, miễn là bạn không quên các bước sau chỉ được chạy trên các payload đã xác minh là JSON hợp lệ.

Khi các lỗi JSON trùng họ, bản thân các lỗi ẩn sau lớp họp về naming và quản lý bí mật. Safe Local Tools chỉ là tấm phản chiếu tốt; kỹ năng dài hơn là chia rạch đường biên—“JavaScript không phải JSON”, “fixture phải qua validator”, và “không được phép chỉnh bí mật trên mạng không kiểm soát”—để không bao giờ phải mở lại các ticket kinh khủng giống nhau.