2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

fetchで404がcatchに入らないのはなぜ?HTTP成功とJSONの読み取りをNode.jsで実測

2
Posted at

404 でも fetch() の catch に入らないことがあります。

HTTP の成功と JSON の読み取りは別の判定です。

macOS 27.2 / Node.js v24.22.1 のローカル HTTP で実測しました。ブラウザ・CORS・認証・リダイレクトは未検証です。

ok が見ているのはステータスが 200〜299 かどうかです。

Q. 実際の結果は?

check-fetch.mjs に保存し、node check-fetch.mjs で実行します。

import http from 'node:http';
import { once } from 'node:events';

const routes = {
  '/missing': [404, 'application/json', '{"error":"not found"}'],
  '/html': [200, 'text/html', '<h1>Login</h1>'],
  '/empty': [204, 'application/json', ''],
  '/ok': [200, 'application/json', '{"name":"Mii"}'],
};
const server = http.createServer((req, res) => {
  const [status, type, body] = routes[req.url] ?? routes['/missing'];
  res.writeHead(status, { 'Content-Type': type });
  res.end(body);
});
server.listen(0, '127.0.0.1');
await once(server, 'listening');
const base = `http://127.0.0.1:${server.address().port}`;

try {
  for (const path of ['/missing', '/html', '/empty', '/ok']) {
    const res = await fetch(base + path);
    console.log(`${path} status=${res.status} ok=${res.ok}`);
    try {
      console.log('json:', JSON.stringify(await res.json()));
    } catch (error) {
      console.log('json error:', error.name);
    }
  }
} finally {
  await new Promise((resolve, reject) => server.close(error => error ? reject(error) : resolve()));
}

出力(例外は種類のみ):

/missing status=404 ok=false
json: {"error":"not found"}
/html status=200 ok=true
json error: SyntaxError
/empty status=204 ok=true
json error: SyntaxError
/ok status=200 ok=true
json: {"name":"Mii"}

Q. catch に集めたいときは?

上の try から使う関数です。HTTP 失敗は自分で例外にします。

async function getJson(path) {
  const res = await fetch(base + path);
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  if (res.status === 204) return null;
  return await res.json();
}

実測でも 404 は Error: HTTP 404、204 は null でした。

204 以外の成功応答が JSON の API 用です。200 の空本文やエラー本文の処理は別途必要です。JSON の値の型も保証しません。

参考:Fetch Standard、Node.js v24.22.1


未経験者向けの体験版を公開しています

※ 中上級者には易しすぎる内容なので、初心者の知り合いへの紹介や社内研修の参考としてどうぞ。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?