Единый формат ошибки
Часть раздела REST API путешествия по Node.js на Coddy. Урок 12 из 25.
Теперь ваш API возвращает ошибки в двух форматах: строку для 404 и объект zod для 400. Клиенту нужно обрабатывать каждый из них. Используйте единый формат для всех ошибок:
{ "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 предназначен для программ: он никогда не меняется, поэтому клиент может сравнивать его. message предназначен для людей, и его формулировка может меняться. fields указывает форме, какое поле ввода нужно отметить. Определите этот формат в одной функции и вызывайте её из каждого маршрута, чтобы форматы маршрутов не расходились:
sendError(res, 404, 'not_found', 'Invoice not found');Задание
ЛегкоТеперь ваш API отправляет ошибки в двух форматах: простую строку для 404 и объект zod для 400. Приведите все ошибки к одному формату, чтобы клиент мог обрабатывать их одинаково. Теперь каждая ошибка выглядит так; fields добавляется, только если есть что перечислить:
{ "error": { "code": "not_found", "message": "Task not found" } }- В
errors.jsзавершите функциюsendError(res, status, code, message, fields). Она отправляет ответ с указанным статусом и приведённой выше структурой. Добавляйтеfieldsво внутренний объект, только если этот аргумент был передан. ФункцияsendInvalidниже уже написана и вызывает вашу функцию. - В
routes/tasks.jsимпортируйте оба вспомогательных средства:- Замените четыре ответа 404 (GET, PATCH, PUT и DELETE для одной задачи) на
sendError, указав кодnot_foundи сообщениеTask not found. - Замените три ответа 400 для некорректного тела запроса (POST, PATCH и PUT) на
sendInvalid(res, result.error).
В таком случае некорректное тело запроса выглядит так (сообщение формирует zod):
{ "error": { "code": "invalid_body", "message": "Invalid input: expected string, received number", "fields": { "title": ["Invalid input: expected string, received number"] } } } - Замените четыре ответа 404 (GET, PATCH, PUT и DELETE для одной задачи) на
- В
server.jsимпортируйтеsendErrorи используйте его в обработчике ошибок внизу:- Если тело запроса не является допустимым JSON, отправьте статус 400, код
invalid_jsonи сообщениеThe body is not valid JSON. - В любом другом случае отправьте статус 500, код
server_errorи сообщениеSomething went wrong.
- Если тело запроса не является допустимым JSON, отправьте статус 400, код
Проверьте: DELETE /api/tasks/99 возвращает 404 с ответом { "error": { "code": "not_found", "message": "Task not found" } } без fields. Отправьте POST-запрос с телом { "title": 123 } на /api/tasks: вы получите 400 с приведённой выше ошибкой invalid_body. Панель запросов не позволяет отправлять некорректный JSON, поэтому проверка протестирует случай invalid_json за вас.
Попробуйте сами
import { z } from 'zod';
// Отправляет все ошибки в едином формате:
// { "error": { "code": "not_found", "message": "Task not found" } }
// при этом "fields" добавляется только в том случае, если оно передано.
export const sendError = (res, status, code, message, fields) => {
// Отправьте ответ здесь
};
// Ошибка zod с кодом 400: первая проблема — в сообщении, проблемы каждого поля —
// в fields.
export const sendInvalid = (res, zodError) =>
sendError(res, 400, 'invalid_body', zodError.issues[0].message, z.flattenError(zodError).fieldErrors);
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела REST API
1Ресурсы и глаголы
Ресурсы и URLСоздание с помощью POST4Браузеры, версии и конфигурация
Что такое originРазрешение другого originCORSСтраница, вызывающая API2Валидация и ошибки
Проверка входных данныхПотренируйтесь самостоятельно: Песочница Express