統一されたエラー形式
CoddyのNode.jsジャーニー「REST API」セクションの一部。レッスン 12/25。
現在、API は 2 種類の形式でエラーに応答します。404 では文字列、400 では zod のオブジェクトです。クライアントはそれぞれに対応する必要があります。すべてのエラーで形式を統一しましょう。
{ "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 は、フォームのどの入力欄に印を付けるかを示します。形式を 1 つの関数にまとめ、すべてのルートから呼び出せば、ルートごとに形式がずれることはありません。
sendError(res, 404, 'not_found', 'Invoice not found');チャレンジ
簡単あなたの API は、エラーを2種類の形式で送るようになりました。404では単なる文字列、400ではzodのオブジェクトです。クライアントがすべてのエラーを同じ方法で読み取れるように、すべてのエラーを同じ形式にしましょう。これからはすべてのエラーが次のようになり、表示する項目がある場合にだけfieldsが追加されます。
{ "error": { "code": "not_found", "message": "Task not found" } }errors.jsで、sendError(res, status, code, message, fields)を完成させましょう。指定されたステータスと上記の形式で応答します。引数が渡された場合にだけ、内側のオブジェクトにfieldsを追加してください。その下のsendInvalidはすでに記述されており、あなたの関数を呼び出します。routes/tasks.jsで、両方のヘルパーをインポートしましょう。- 1つのタスクに対する4つの404応答(GET、PATCH、PUT、DELETE)を
sendErrorに置き換え、コードにはnot_found、メッセージにはTask not foundを使います。 - 不正な本文に対する3つの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"] } } }- 1つのタスクに対する4つの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は、{ "error": { "code": "not_found", "message": "Task not found" } }とともに404を返し、fieldsは含まれません。{ "title": 123 }を/api/tasksにPOSTすると、上記のinvalid_bodyエラーとともに400が返ります。リクエストバーは不正な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のすべてのレッスン
自分で練習してみよう: Expressプレイグラウンド