Kodokon kodokon.com

デバッグと堅牢性: try/catch、高度な console、カスタムエラー

専用のクラス、うまく配置された catch 境界、そして持てる力を存分に発揮した console によって、明示的なエラー戦略を築きましょう。

9 分 · 3 問

このレッスンを Kodokon で開く

堅牢性とは、あらゆるエラーを捕捉することではなく、適切な場所で それらを捕捉することです。現場の鉄則は、バグにできるだけ近い場所で早く大きく失敗すること(検証、不変条件)、そして実際に対応できる 境界(メッセージを表示する、再試行する、ログを取る)でのみ捕捉することです。何の役にも立たない try/catch はコードをより安全にしません。失敗を沈黙させるだけです。

JAVASCRIPT
function parseConfig(json) {
  try {
    return JSON.parse(json);
  } catch (error) {
    console.error("Unreadable config:", error.message);
    throw error; // rethrow: nothing can be fixed here
  } finally {
    console.log("Finished reading configuration");
  }
}
ログを取り、それから再スロー。上の境界が判断します。

ただの文字列ではエラー戦略になりません。Error を拡張して、instanceof で識別できる 構造化データ(HTTP ステータス、無効なフィールド)を持つクラスを作りましょう。ES2022 以降、cause オプションは元のエラーを高レベルのエラーに連鎖させます。技術的な手がかりを失うことなく、明確な業務メッセージを露出できます。

JAVASCRIPT
class ApiError extends Error {
  constructor(message, status, options) {
    super(message, options);
    this.name = "ApiError";
    this.status = status;
  }
}
try {
  const low = new Error("socket timeout");
  throw new ApiError("Profile unavailable", 503,
    { cause: low });
} catch (error) {
  if (error instanceof ApiError) {
    console.error(error.status, error.cause.message);
  }
}
技術的な原因を保ったまま識別できる業務エラー。

console は log よりずっと多くを提供します。console.table はオブジェクトのコレクションを整列させ、group/groupEnd は出力を入れ子にし、time/timeEnd は所要時間を測り、console.assert は条件が偽の とき にのみログを出し、console.trace は現在のコールスタックを表示します。組み合わせれば、これらのツールは名もなき log の土砂降りを圧倒的に凌駕します。

JAVASCRIPT
const users = [
  { name: "Ada", role: "admin" },
  { name: "Linus", role: "dev" },
];
console.table(users);
console.group("Checks");
console.assert(users.length > 0, "Empty list");
console.time("sort");
users.sort((a, b) => a.name.localeCompare(b.name));
console.timeEnd("sort");
console.groupEnd();
構造化された出力: テーブル、グループ、アサーション、タイマー。

理解度チェック

このレッスンの要点をしっかり覚えているか確認しましょう。

  1. finally ブロックはいつ実行されますか?
    • エラーが投げられなかった場合のみ
    • catch が起動された場合のみ
    • return や throw の後を含め、あらゆる場合に
  2. エラーを構築するときの cause オプションは何のためのものですか?
    • エラーが伝播するのを防ぐため
    • 元のエラーを添付し、技術的な文脈を保つため
    • HTTP ステータスコードを自動的に設定するため
    • 新しい catch を起動するため
  3. console.assert(condition, message) の挙動は何ですか?
    • 条件が偽の場合にのみメッセージをログ出力する
    • 条件が偽の場合に例外を投げる
    • 条件が真の場合にのみメッセージをログ出力する