Menu
CoddyTech

Một cấu trúc lỗi

Thuộc phần REST API trong hành trình Node.js của Coddy. Bài học 12 trên 25.

API của bạn hiện trả lời lỗi theo hai dạng: một chuỗi cho 404 và một đối tượng của zod cho 400. Client phải xử lý từng dạng. Hãy chọn một dạng cho mọi lỗi:

{ "error": { "code": "not_found", "message": "Invoice not found" } }

{ "error": { "code": "invalid_body", "message": "Too small: ...",
             "fields": { "amount": ["Too small: expected number to be >0"] } } }

code dành cho chương trình: giá trị này không bao giờ thay đổi, nên client có thể so sánh. message dành cho mọi người và cách diễn đạt có thể thay đổi. fields cho biểu mẫu biết cần đánh dấu ô nhập nào. Hãy viết cấu trúc này trong một hàm rồi gọi hàm đó từ mọi route để các route luôn thống nhất:

sendError(res, 404, 'not_found', 'Invoice not found');
challenge icon

Thử thách

Dễ

Giờ đây, API của bạn gửi lỗi theo hai dạng: chuỗi đơn giản cho lỗi 404 và đối tượng của zod cho lỗi 400. Hãy dùng cùng một dạng cho mọi lỗi để ứng dụng khách có thể đọc tất cả theo cùng một cách. Từ giờ, mọi lỗi đều có dạng như sau, chỉ thêm fields khi có nội dung cần liệt kê:

{ "error": { "code": "not_found", "message": "Task not found" } }
  1. Trong errors.js, hoàn thiện sendError(res, status, code, message, fields). Hàm này phản hồi bằng trạng thái được cung cấp và có dạng như trên. Chỉ thêm fields vào đối tượng bên trong khi có cung cấp đối số đó. sendInvalid bên dưới đã được viết sẵn và gọi hàm của bạn.
  2. Trong routes/tasks.js, nhập cả hai hàm hỗ trợ:
    • Thay bốn phản hồi 404 (GET, PATCH, PUT và DELETE cho một tác vụ) bằng sendError, dùng mã not_found và thông báo Task not found.
    • Thay ba phản hồi 400 cho nội dung yêu cầu không hợp lệ (POST, PATCH và PUT) bằng sendInvalid(res, result.error).

    Nội dung yêu cầu không hợp lệ sẽ có dạng như sau (zod tạo thông báo):

    {
      "error": {
        "code": "invalid_body",
        "message": "Invalid input: expected string, received number",
        "fields": { "title": ["Invalid input: expected string, received number"] }
      }
    }
  3. Trong server.js, nhập sendError và dùng hàm này trong trình xử lý lỗi ở cuối tệp:
    • Nếu nội dung yêu cầu không phải JSON hợp lệ, hãy trả về trạng thái 400, mã invalid_json và thông báo The body is not valid JSON.
    • Với mọi trường hợp khác, hãy trả về trạng thái 500, mã server_error và thông báo Something went wrong.

Thử nhé: DELETE /api/tasks/99 trả về 404 với { "error": { "code": "not_found", "message": "Task not found" } } và không có fields. Gửi POST { "title": 123 } đến /api/tasks: bạn sẽ nhận được lỗi 400 với lỗi invalid_body ở trên. Thanh yêu cầu không cho gửi JSON sai định dạng, nên các bước kiểm tra sẽ kiểm tra trường hợp invalid_json thay bạn.

Tự làm thử

import { z } from 'zod';

// Gửi mọi lỗi theo cùng một cấu trúc:
// { "error": { "code": "not_found", "message": "Task not found" } }
// chỉ thêm "fields" khi có giá trị này.
export const sendError = (res, status, code, message, fields) => {
    // Gửi kết quả tại đây
};

// Gửi lỗi zod với mã 400: dùng vấn đề đầu tiên làm thông báo, còn các vấn đề của từng trường
// đưa vào fields.
export const sendInvalid = (res, zodError) =>
    sendError(res, 400, 'invalid_body', zodError.issues[0].message, z.flattenError(zodError).fieldErrors);
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong REST API

Tự luyện tập: Playground Express