try-catch-finally の基本|JavaScript

JavaScript でエラーが発生すると、通常はそこでプログラムの実行が止まってしまいます。try-catch-finally を使うと、エラーが起きても処理を継続したり、適切な対応を取ったりできます。

基本構文

try {
  // エラーが起きるかもしれない処理
} catch (error) {
  // エラーが起きたときの処理
} finally {
  // 必ず実行される処理
}

try ブロックの中でエラーが発生すると、即座に catch ブロックへ移動します。finally ブロックはエラーの有無にかかわらず、最後に必ず実行されます。

実際の例

try {
  const data = JSON.parse('{"name": "Alice"}');
  console.log(data.name);
} catch (error) {
  console.error('JSONのパースに失敗しました');
} finally {
  console.log('処理が完了しました');
}

この例では JSON のパースを試み、失敗した場合はエラーメッセージを表示します。成功しても失敗しても「処理が完了しました」が出力されます。

catch ブロックで受け取る error オブジェクト

catch の引数にはエラーオブジェクトが渡されます。このオブジェクトには、エラーの詳細情報が含まれています。

try {
  const result = undefinedVariable + 1;
} catch (error) {
  console.log(error.name);    // "ReferenceError"
  console.log(error.message); // "undefinedVariable is not defined"
}

error.name でエラーの種類、error.message でエラーの内容を取得できます。

finally の用途

finally はリソースの解放やクリーンアップ処理に使われることが多いです。

let connection = null;

try {
  connection = openDatabase();
  // データベース操作
} catch (error) {
  console.error('データベースエラー:', error.message);
} finally {
  if (connection) {
    connection.close(); // 必ず接続を閉じる
  }
}

エラーが起きても起きなくても、データベース接続は確実に閉じられます。

catch や finally の省略

catch と finally は、どちらか一方だけでも構いません。

// catch のみ
try {
  riskyOperation();
} catch (error) {
  handleError(error);
}

// finally のみ(エラーは再スローされる)
try {
  riskyOperation();
} finally {
  cleanup();
}

ただし、finally のみの場合、エラーは捕捉されずに上位へ伝播する点に注意してください。

ネストした try-catch

try-catch はネストすることも可能です。内側で捕捉されなかったエラーは外側の catch で処理されます。

try {
  try {
    throw new Error('内側のエラー');
  } finally {
    console.log('内側の finally');
  }
} catch (error) {
  console.log('外側で捕捉:', error.message);
}

この場合、「内側の finally」が先に実行され、その後「外側で捕捉: 内側のエラー」が出力されます。