2
0

More than 1 year has passed since last update.

【JavaScript】例外処理

Last updated at Posted at 2022-01-03

概要

JavaScriptを学習、理解を深めるため「JavaScript Primer 迷わないための入門書」を読み、
理解した内容等を記載していく。

【JavaScript】JavaScript入門一覧」に他の記事をまとめています。

この記事で理解できること

  • JavaScriptにおける例外処理の方法
  • try...catch構文、throw文の概要

try...catch構文

「try...catch」構文には、構成する以下のブロックキーワードが存在する。

  • try
  • catch
  • finally

例外(exception)とは
想定ができていた(想定内の)エラー
「例:外部から〇〇を取得する処理だけど、HTTPステータス 403(権限が無かった等で失敗)のレスポンスがあるかもしれない」と想定できていたエラーなど

★覚えておこう

try...catch構文ではcatchもしくはfinallyブロックのいずれかは必須となる。
組み合わせとしては以下3パターンが想定される。
try...catch...finally
try...catch(finallyブロック省略)
try...finally(catchブロック省略)

try(ブロック)

  • 例外発生が想定される処理はtryブロックに記述する。
  • tryブロック内で例外が発生した場合
    • それ以降のtryブロック内の処理は実行されずcatchブロックへ処理が移行される。
// ...省略

try {
  // tryブロック:例外発生が想定される処理を記載
  console.log('【tryブロック】処理を開始します】');
  const value = '初期値';
  
  // constで宣言された変数のため例外エラーが発生する
  value = 'constで宣言された変数に再代入';

  // tryブロックでは例外が発生した処理以降は実行されず、catchブロックへ処理が移行する
  console.log('例外発生時この処理含め、以降の処理は実行されない');
  console.log('【tryブロック】処理を終了します');
}

// ...省略

catch(ブロック)

  • tryブロックの処理で例外が発生した場合、エラーをキャッチし、catchブロック内の処理に移る。
  • catchブロック内でのみ参照が可能な例外の値を保持する例外識別子が存在する(下記、例のcatch (error) {..}の「error」箇所)
// ...省略

catch (error) { 
  // catchブロック:例外が発生した場合に実行したい処理を記載
  console.log('【catchブロック】処理を開始します');
  console.log(error);
  console.log('【catchブロック】処理を終了します');
}

// ...省略

finally(ブロック)

  • tryブロックでの例外発生有無に関わらず、必ず最後に処理が実行されるブロック。
  • catchブロックを省略した場合は、finallyブロックの処理を実行後、例外が発生。
finally {
  // finallyブロック:例外発生有無は関係なく一連の処理で最後に行いたい処理を記載
  console.log('【finallyブロック】処理を開始します');
  console.log('一連の処理で最後に行われる処理');
  console.log('【finallyブロック】処理を終了します');
}

例:一連の処理(関数の場合)

function exceptionSample() {
  console.log('【処理1】を開始します');

  try {
    // tryブロック:例外発生が想定される処理を記載
    console.log('【tryブロック】処理を開始します');
    const value = '初期値を代入';

    // constで宣言された変数のため例外エラーが発生する
    value = 'constで宣言された変数に再代入';

    // tryブロックでは例外が発生した処理以降は実行されず、catchブロックへ処理が移行する
    console.log('例外発生時この処理含め、以降の処理は実行されない');
    console.log('【tryブロック】処理を終了します');
  } catch (error) { 
    // catchブロック:例外が発生した場合に実行したい処理を記載
    console.log('【catchブロック】処理を開始します');

    // キャッチしたエラーの内容を出力
    console.log('キャッチしたerrorの内容を出力')
    console.log(error);

    console.log('【catchブロック】処理を終了します');
  } finally {
    // finallyブロック:例外発生有無は関係なく一連の処理で最後に行いたい処理を記載
    console.log('【finallyブロック】処理を開始します');
    console.log('一連の処理で最後に行われる処理');
    console.log('【finallyブロック】処理を終了します');
  }

  console.log('【処理2】を開始します');
};

exceptionSample();

// => 【処理1】を開始します
// => 【tryブロック】処理を開始します
// => 【catchブロック】処理を開始します
// => キャッチしたerrorの内容を出力
// => TypeError: Assignment to constant variable.
// => 【catchブロック】処理を終了します
// => 【finallyブロック】処理を開始します
// => 一連の処理で最後に行われる処理
// => 【finallyブロック】処理を終了します
// => 【処理2】を開始します

例外を投げる方法

tryブロックの処理内で結果(の条件)によっては例外とみなしたい場合など、
throw文を用いてユーザー定義(こちらの都合で)の例外をcatchブロックへ投げることができる。

※throw文を用いて、catchブロックへ処理を移行することを「(catchブロックへ)例外を投げる」と表現されることが多いです。

throw文の前に...エラーオブジェクト(Error)について

  • throw文では例外としてエラーオブジェクトを投げることが可能。
  • エラーオブジェクトはJavaScriptの標準組み込みオブジェクトである、Errorオブジェクトをインスタンス化(new Error())することで生成可能。
  • 第一引数にはエラーメッセージを設定する。
  • エラーメッセージは例外識別子(下記例では「error」)のmessageプロパティで参照可能。

throw文

  • throw文を使用し、catchブロックに対し例外を投げる。
  • 例外は、オブジェクトとして投げられる。
  • また、あらゆるオブジェクトを例外として投げることができるが、Errorオブジェクトのインスタンスを投げることが推奨されている。

例:数値を比較し条件を満たさない場合は、throw文で例外を投げる

exception.js
function exceptionSample() {
  console.log('【処理1】を開始します');

  try {
    // tryブロック:例外発生が想定される処理を記載
    console.log('【tryブロック】処理を開始します');

    const value = -1;

    if (value < 0) {
      throw new Error("0より小さい値なので例外を投げました");
    }

    console.log('【tryブロック】処理を終了します');
  } catch (error) { 
    // catchブロック:例外が発生した場合に実行したい処理を記載
    console.log('【catchブロック】処理を開始します');

    // キャッチしたエラーの内容を出力
    console.log('キャッチしたオブジェクトerrorのメッセージを出力')
    console.log(error.message);

    // tryブロックでは例外が発生した処理以降は実行されず、catchブロックへ処理が移行する
    console.log('【catchブロック】処理を終了します');
  } finally {
    // finallyブロック:例外発生有無は関係なく一連の処理で最後に行いたい処理を記載
    console.log('【finallyブロック】処理を開始します');

    console.log('一連の処理で最後に行われる処理');

    console.log('【finallyブロック】処理を終了します');
  }

  console.log('【処理2】を開始します');
};

exceptionSample();

// => 【処理1】を開始します
// => 【tryブロック】処理を開始します
// => 【catchブロック】処理を開始します
// => キャッチしたerrorの内容を出力
// => Error: 0より小さい値なので例外を投げました
// => 【catchブロック】処理を終了します
// => 【finallyブロック】処理を開始します
// => 一連の処理で最後に行われる処理
// => 【finallyブロック】処理を終了します
// => 【処理2】を開始します

番外編:try..catch構文で例外処理をしない場合

例外処理をしない場合、例外が発生した時点で処理が終了してしまいます。
例外が発生しうる処理を行う場合は、try..catch構文を使用することが得策ですね!

これまでの例では「【処理2】を開始します」というログを出力していましたが、
下記では【処理1】で例外が発生して終了していることが確認できます。

function exceptionSample() {
  console.log('【処理1】を開始します');

  const value = '初期値';
  // ここで例外が発生する
  value = '再代入はできない'

  // 以降の処理は実行されず終了する
  console.log('例外発生時ここ以降の処理は実行されない');
  console.log('【処理2】を開始します');
};

exceptionSample();

// => 【処理1】を開始します
// => ncaught TypeError: Assignment to constant variable...
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