Skip to main content

Lỗi resolver được trả về với HTTP 200

Đây là điều quan trọng nhất cần biết trước khi bạn viết phần xử lý lỗi. Theo đặc tả GraphQL over HTTP, một request đến được resolver của chúng tôi sẽ trả về HTTP 200 ngay cả khi một thao tác thất bại. Lỗi được báo cáo bên trong body phản hồi, không phải bằng mã trạng thái. Vì vậy cách kiểm tra này không hoạt động:
Thay vào đó hãy kiểm tra body. Một vài lỗi truyền tải, chẳng hạn 415 cho Content-Type không được hỗ trợ, có body rỗng, vì vậy hãy kiểm tra phản hồi có phải JSON không trước khi phân tích cú pháp:
Một số lỗi được phát hiện trước khi bất cứ thứ gì chạy. Không lỗi nào trong số đó đến được resolver hoặc tiêu tốn lệnh gọi API:
  • Một request sai định dạng trả về mã trạng thái lỗi: HTTP 400 cho JSON không hợp lệ hoặc thiếu query, 413 cho body lớn hơn 64 KB, 405 cho phương thức khác POST, và 415 cho Content-Type không được hỗ trợ.
  • Một truy vấn không hợp lệ theo schema chỉ trả về HTTP 400 nếu request của bạn gửi Accept: application/graphql-response+json. Điều này bao gồm lỗi cú pháp, trường không xác định, sai kiểu đối số, giá trị enum không hợp lệ, và truy vấn vượt quá giới hạn truy vấn. Nếu bạn gửi Accept: application/json, hoặc không có header Accept, cùng lỗi đó sẽ trả về HTTP 200. Dù theo cách nào, body cũng có một mảng errors và không có data.
Khi quá trình thực thi bắt đầu, các lỗi xác thực input ở cấp resolver và lỗi API — bao gồm xác thực, phân quyền, giới hạn tốc độ phía upstream và phản hồi 5xx phía upstream — đều trả về HTTP 200 kèm một mảng errors.

Cấu trúc lỗi

Mọi lỗi resolver đều mang trạng thái API tương tự HTTP trong extensions:
  • message — mô tả dễ đọc cho con người. Chúng tôi loại bỏ API key và các thông tin xác thực khác khỏi thông báo lỗi resolver, nhưng một lỗi về giá trị bạn đã gửi, chẳng hạn một biến sai kiểu, có thể lặp lại giá trị đó. Hãy coi message là có thể nhạy cảm trước khi ghi log.
  • path — trường nào trong truy vấn của bạn bị lỗi. Khi có nhiều trường trong một request, đây là cách bạn biết trường nào.
  • extensions.status — mã trạng thái HTTP mà lệnh gọi REST tương đương sẽ trả về. Hãy rẽ nhánh xử lý dựa trên giá trị này.
  • extensions.code — mã lỗi Ayrshare dạng số, khi endpoint bên dưới cung cấp.
  • extensions.retryAfter — có mặt trong các lỗi 429 do hạn mức hoặc giới hạn tốc độ phía upstream khi có sẵn thời gian chờ thử lại. Nó không có mặt trong lỗi 429 do ngân sách dispatch theo từng request.
Hãy dùng extensions.code với tài liệu tham khảo mã lỗi, hoặc truyền nó vào explainError.

Thành công một phần

Nếu một request yêu cầu nhiều thứ và chỉ một số thành công, bạn sẽ nhận được cả data và errors:
history đã thành công và dữ liệu của nó có thể sử dụng. Chỉ analytics cần thử lại. Đừng loại bỏ toàn bộ phản hồi chỉ vì có errors — làm vậy sẽ vứt bỏ dữ liệu mà bạn đã bị tính phí.

Thành công một phần với bài đăng trên nhiều mạng xã hội

Một bài đăng lên nhiều mạng xã hội có thể thành công trên một số mạng và thất bại trên những mạng khác. Điều này không được báo cáo là lỗi GraphQL, vì bản thân thao tác đã hoạt động — nó đã làm chính xác những gì bạn yêu cầu và đang cho bạn biết điều gì đã xảy ra. Kết quả tách riêng ba kết cục:
  • postIds — các mạng xã hội đã xuất bản, cùng URL bài đăng. Chỉ bao gồm các trường hợp thành công.
  • errors — các mạng xã hội thất bại, kèm lý do.
  • blocked — các mạng xã hội bị dừng trước khi thử, ví dụ bởi circuit breaker theo từng mạng xã hội sau các lỗi xác định lặp lại. Những mục này tách biệt với các lần thử gửi đến nhà cung cấp đã trả về lỗi.
status là "error" nếu bất kỳ mạng xã hội nào thất bại, vì vậy nó không phải là tín hiệu đáng tin cậy cho thấy không có gì được xuất bản. Hãy đọc postIds để biết những gì đã được xuất bản.

Thử lại

GraphQL API không bao giờ tự động thử lại. Nếu một request thất bại, không có gì được âm thầm thử lại thay cho bạn. Điều này quan trọng nhất đối với mutation. createPost cung cấp idempotencyKey: hãy tạo một key duy nhất trước lần thử đầu tiên, sau đó dùng lại cùng key đó và payload giống hệt cho mọi lần thử lại. Một lần thử lại đã hoàn tất sẽ phát lại kết quả ban đầu thay vì lặp lại thao tác ghi. Đừng chuyển sang key mới sau một phản hồi không rõ ràng. boostFacebookPost và instagramBoostPost cũng nhận idempotencyKey, và nó bảo vệ tiền thật. Một lần thử lại với cùng key và cùng đối số sẽ trả về kết quả ban đầu, được đánh dấu idempotentReplayed: true, thay vì tạo và trả tiền cho một quảng cáo thứ hai. Một key áp dụng cho toàn bộ tài khoản của bạn trên cả hai nền tảng Meta, vì vậy đừng bao giờ dùng lại key của một lần boost Facebook cho một lần boost Instagram. Khi một key bị từ chối, extensions.status cho bạn biết lý do. createPost trả về 409 khi lần thử đầu tiên vẫn đang được xử lý, vì vậy hãy chờ và thử lại với cùng key, và trả về 400 khi payload khác với lần thử đầu tiên. Các mutation boost trả về 409 trong cả hai trường hợp, và cả khi key đã được dùng cho một lần boost trên nền tảng còn lại. Các thao tác ghi khác, chẳng hạn addComment, không có idempotency key. Nếu phản hồi của chúng bị mất, hãy kiểm tra mạng xã hội hoặc trạng thái API trước khi quyết định liệu thử lại có an toàn hay không. Hai giới hạn khác nhau đều báo cáo 429, và chúng cần được xử lý khác nhau. Ngân sách dispatch chỉ từ chối các trường gốc khi đã có năm lệnh gọi API bắt đầu trong cùng một request, và thông báo của nó bắt đầu bằng Query exceeds the per-request dispatch budget: hãy chia các trường đó thành các request có tối đa năm trường, không cần chờ. Bất kỳ lỗi 429 nào khác là giới hạn tốc độ hoặc hạn mức: hãy chờ extensions.retryAfter giây khi có giá trị này, nếu không thì hãy lùi thời gian (back off) trước khi thử lại, và chỉ thử lại các trường đã thất bại. Với lỗi 5xx trên một thao tác đọc, việc thử lại là an toàn, với một ngoại lệ: generatePost là một query, nhưng một lần thử lại sẽ gọi lại trình tạo AI, được tính là một lệnh gọi API khác, và trả về văn bản khác. Với lỗi 5xx trên một thao tác ghi không có idempotency, hãy đối chiếu xem nó đã có hiệu lực chưa trước khi thử lại.

Các trạng thái phổ biến

Các lỗi do chính GraphQL phát sinh trước khi thực thi, chẳng hạn trường không xác định, sai kiểu đối số, hoặc giá trị enum không hợp lệ, không có extensions.status. Chúng trả về HTTP 400 hoặc 200 tùy thuộc vào header Accept của bạn, như đã mô tả ở trên. Chúng có nghĩa là bản thân truy vấn sai, và không có lệnh gọi API nào được thực hiện hoặc tính phí.