Um único formato de erro
Parte da seção APIs REST do Journey de Node.js da Coddy. Lição 12 de 25.
Sua API responde a erros de duas formas agora: uma string para um 404 e o objeto do zod para um 400. Um cliente precisa lidar com cada uma delas. Escolha uma forma para todos os erros:
{ "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 é para programas: nunca muda, então um cliente pode compará-lo. message é para pessoas, e seu texto pode mudar. fields informa a um formulário qual campo de entrada deve ser marcado. Escreva a estrutura em uma função e chame-a em todas as rotas, para que nenhuma rota fique diferente das outras:
sendError(res, 404, 'not_found', 'Invoice not found');Desafio
FácilSua API agora envia erros em dois formatos: uma string simples para um 404 e o objeto do zod para um 400. Dê a todos os erros o mesmo formato, para que um cliente possa lê-los sempre da mesma maneira. A partir de agora, todo erro fica assim, com fields adicionado apenas quando houver algo para listar:
{ "error": { "code": "not_found", "message": "Task not found" } }- Em
errors.js, concluasendError(res, status, code, message, fields). Ele responde com o status informado e o formato acima. Adicionefieldsao objeto interno somente quando esse argumento for informado.sendInvalid, logo abaixo, já está escrito e chama sua função. - Em
routes/tasks.js, importe os dois auxiliares:- Substitua as quatro respostas 404 (GET, PATCH, PUT e DELETE para uma tarefa) por
sendError, usando o códigonot_founde a mensagemTask not found. - Substitua as três respostas 400 para um corpo inválido (POST, PATCH e PUT) por
sendInvalid(res, result.error).
Um corpo inválido fica assim (o zod escreve a mensagem):
{ "error": { "code": "invalid_body", "message": "Invalid input: expected string, received number", "fields": { "title": ["Invalid input: expected string, received number"] } } } - Substitua as quatro respostas 404 (GET, PATCH, PUT e DELETE para uma tarefa) por
- Em
server.js, importesendErrore use-o no manipulador de erros no final:- Um corpo que não seja JSON válido recebe o status 400, o código
invalid_jsone a mensagemThe body is not valid JSON. - Qualquer outra coisa recebe o status 500, o código
server_errore a mensagemSomething went wrong.
- Um corpo que não seja JSON válido recebe o status 400, o código
Teste: DELETE /api/tasks/99 retorna 404 com { "error": { "code": "not_found", "message": "Task not found" } }, sem fields. Envie { "title": 123 } por POST para /api/tasks: você recebe 400 com o erro invalid_body acima. A barra de requisições se recusa a enviar JSON inválido, então as verificações testam o caso invalid_json para você.
Experimente você mesmo
import { z } from 'zod';
// Envia todos os erros em um único formato:
// { "error": { "code": "not_found", "message": "Task not found" } }
// com "fields" adicionado somente quando fornecido.
export const sendError = (res, status, code, message, fields) => {
// Envie a resposta aqui
};
// Um erro do zod como um 400: o primeiro problema como mensagem, os problemas de cada campo
// em fields.
export const sendInvalid = (res, zodError) =>
sendError(res, 400, 'invalid_body', zodError.issues[0].message, z.flattenError(zodError).fieldErrors);
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de APIs REST
1Recursos e verbos
Recursos e URLsCriando com POST4Navegadores, versões e configuração
O que é uma origemPermitindo outra origemCORSUma página que chama a API2Validação e erros
Validando a entradaPratique por conta própria: Playground de Express