サイトロゴ

Enjoy Creating
Web & Mobile Apps

MENU BOX
WEB
MOBILE
OPEN

ホーム

 > 

 > 

【JavaScript】ユーザー定義のエラー発生と捕捉【throw/try-catch】

【JavaScript】ユーザー定義のエラー発生と捕捉【throw/try-catch】

この記事にはプロモーションが含まれています。

プログラミングを学んでいく中で、決して避けて通れないのがエラー(例外)です。

初めは、ログにエラーメッセージが表示されるだけでもなんだかちょっと怖いというか、ドキっとしちゃいますよね。笑

ある程度プログラミングに慣れてくると、エラー発生→エラーメッセージをしっかり読んで理解する→問題がありそうな所を修正する…という基本が身についてきます。

そしてこのレベルまで達すると、大体のエラーは解決することができるようになります。(もちろん、エラーメッセージを読んでもよくわからない意味不明なエラーには苦労させられるのですが…)

しかし、エラーとの向き合い方はこれで終わりではありません。

そもそも、エラーメッセージってどうやって用意されるのでしょうか?コンピュータが気を利かせて、勝手に作り出しているものなのでしょうか?

もちろん、そんなことあるわけないですよね。

的確なエラーメッセージが表示されるのは、プログラムを開発した人が、『この処理はこういう例外が起こり得るだろうな』という状況を先読みして、『こういう場合はこういうエラーメッセージを表示させるようにしておこう』というふうに、設計してくれているからこそなのです。

この一連の流れは、ユーザー定義の例外発生・例外の捕捉と表現されます。

この流れを理解することで、よりエラー発生とその処理の流れが明確になり、エラーともっと仲良くなれること間違いなしです!笑

なお、"例外"よりも、"エラー"という言葉の方が馴染み深いと思うので、基本的には『エラー』という言葉を優先的に使用して、解説を進めていきます。

この記事を読むことで分かること
  • ・ユーザー定義のエラーをスローする方法
  • ・try-catch文の基本
  • ・捕捉したエラー情報を利用する方法

– 目次 –

ユーザー定義のエラーをスロー(投げる)

まず、ユーザー定義のエラーとは何かについて、軽く触れておこうと思います。

そもそも、プログラミング言語の文法(ルール)的に間違った記述をした場合は、開発者が何か特別なエラー処理を定義していなくても、適切なエラーメッセージが表示されるようになっていますよね。

例えば、constで宣言した定数に、後から違う値を代入しようとしてもエラーになり、エラーメッセージがログに表示されます。

JavaScript

const message = "Hello";
message = "World!"; // Uncaught TypeError: Assignment to constant variable.

これはプログラミング言語側でもともと用意されたエラー処理であり、エラー処理を定義する開発者が気にしなければならないポイントではありません。

しかし、例えば動的型付け言語であるJavaScriptでは、開発者が定義した関数の引数としてどんな型のデータが渡されるかに関しては、言語側でエラーをチェックするような機能は備えていません。

下のように、引数に数値(number)型のデータが渡されることを期待して、秒を分に変換したメッセージ(文字列)を得る関数があったとしましょう。

JavaScript

function secondsToMinutes(second) {
    return `${second}秒は${second / 60}分です`;
}

この時、開発者はパラメータ(second)には数値が渡されることを想定しています。

すなわち、数値以外の文字列(String)や真偽値(Boolean)が渡されてしまうことは想定外ということになります。

ですが、動的型付け言語であるJavaScriptでは、文法的にsecondsToMinutesの引数(second)として文字列や真偽値を渡すことは問題ありません。

JavaScript

function secondsToMinutes(second) {
    return `${second}秒は${second / 60}分です`;
}

// コンソールに出力
console.log(secondsToMinutes(false)); // -> false秒は0分です

何のエラーメッセージも表示されないため、これでは間違った関数の使われ方をしてしまうかもしれませんよね。

そのため、プログラミング言語の文法的には正しくても、ユーザーが定義する例外(エラー)を発生させることができるようになっています。

ユーザー定義の例外を発生させるには、throwを使ってErrorインスタンスを作成します。

JavaScript

function secondsToMinutes(second) {
    if(typeof(second) !== "number") {
        throw new Error('Parameter is not a number!');
    }
    return `${second}秒は${second / 60}分です`;
}

// コンソールに出力
console.log(secondsToMinutes(false)); // Uncaught Error: Parameter is not a number!
ユーザー定義のエラーログメッセージ表示画面

上のコードでは、if文の中で渡された引数が数値(number型)であるかどうかを判定し、数値ではない場合はユーザー定義のエラーをスローするようにしています。

こうすることにより、真偽値を渡してsecondsToMinutes()関数を実行しようとすると、ユーザーが定義したエラーメッセージ『Uncaught Error: Parameter is not a number!』がログに表示されるようになりました。

これで、とりあえず数値(number)以外のデータ型が引数にされた場合のエラー対応はできました。

『とりあえず』と言ったのは、このままではエラー発生後の処理のカスタマイズ等ができないからです。

例えば、エラーメッセージを表示させるだけでなく、エラーログをサーバーに転送して記録したり…といった処理を追加したいと思っても、throw文の後に書かれた処理は実行されません。

JavaScript

function secondsToMinutes(second) {
    if(typeof(second) !== "number") {
        throw new Error('Parameter is not a number!');
        console.error("数値以外は受け付けないよ!"); // 実行されない
    }
    return `${second}秒は${second / 60}分です`;
}

// コンソールに出力
console.log(secondsToMinutes(false)); // Uncaught Error: Parameter is not a number!

console.error(“数値以外は受け付けないよ!”)…の部分は実行されず、ログには『Parameter is not a number!』のメッセージのみが表示されます。

これではせっかくエラーを定義しても、そのエラーを利用した処理ができないのでちょっと使い勝手が悪いですよね。

そこで、次のステップでは、try-catch文を使ってスローされたエラーを捕捉して、エラー処理をアレンジしてみましょう!

    POINT!
  1. ・ユーザー定義のエラーとは、プログラミング言語側で用意されていない独自のエラー定義!
  2. ・throw new Error()でユーザー定義のエラーオブジェクトを生成できる!
  3. ・throw文の後に何か処理を書いても実行されない!

エラーを捕捉してエラー後処理をアレンジ

ユーザー定義のエラーが発生した場合、エラーをスローするだけでなく、エラーを捕捉した上でその後の処理をより適切にするには、try-catch文を使います。

try-catchの構文は以下の通りです。

JavaScript

try {
    // 例外が発生するかもしれない処理
} catch(exceptionVar) { // 例外変数
    // tryブロックの中で例外が発生した場合に行う処理
}

tryブロックでは、前の章のサンプルのようにエラーが起こる可能性がある処理を記述することで、まずその処理の実行が試みられます。

catchブロックでは、tryブロックの中で例外が発生した場合にスローされたエラーをcatch(捕捉)し、捕えたエラーを例外変数に格納することで、エラーに対するその後の処理を行うことができます。(エラーの内容を直接ユーザーに見える形で表示したりなど)

exceptionVar(例外変数)は、略してeと記載される場合が多いですね。(もしくはerrorなど)

ちなみに、捕捉されたエラーの情報をcatchブロックで利用しない場合は、exceptionVar(例外変数)は省略可能です。

捕捉されたエラーの情報はどうでもいいから、とにかく何らかの処理を行いたい場合は省略できると思っておくと良いでしょう。

それでは、try-catch文の基本を押さえたところで、前章のサンプルコードに改良を加えていきましょう。

前章ではエラーをスローするだけでしたが、ここではスローされたエラーをtry-catch文で捕捉し、エラーをコンソールだけでなくspan要素のテキストとしても表示させることで、ユーザーがコンソールを開かなくてもエラーを確認できるようにしてみたいと思います。

前章で登場した、secondsToMinutes(second)関数は例外が起こり得る処理と言えるので、これをtryブロックの中で実行します。

そして、catchブロックで捕捉されたエラー情報を利用して、要素の文字列として表示させます。

下のCodePenで、コードと表示結果を同時にご確認いただけます。

See the Pen Untitled by ROYDO (@roydo) on CodePen.

エラーメッセージがページ上にテキストとして表示されていることが確認できますね。

catchブロックでは、console.error(e) により、コンソール画面にエラーを表示させるとともに、displayErrorElm.textContent = e により、捕捉したエラー情報(eに格納されている)をテキストとして表示させています。

エラーをスローしただけではその後の処理ができませんでしたが、try-catch文によって、エラー発生後の処理にアレンジを加えることができるようになったと言えます。

これを応用すると、たとえばアプリがエラーによって強制終了された場合に、品質改良のためエラーログを開発元に送信するように求めたりできます。

たまに見かけますよね。『予期しないエラーが発生しました。このエラーを報告しますか?はい・いいえ』…みたいなやつ。あれです。

ただ『エラーが発生しました』だけで終わらせないことで、エラーの原因を突き止めたり、次の製品開発のヒントにしたりできるというわけですね。

エラーが起こらないに越したことはないですが、エラー情報は、問題解決のために役立つ強力な味方です。

プログラミング初心者のうちから、エラーは憎むべき敵ではなく有能な味方だという認識を身に付けておくと、エラーが怖くなくなり、プログラミングの学習がさらに楽しくなってくると思います。

そのためにも、throwによるエラーのスローと、try-catch文の基本はしっかり押さえておきましょう!

    POINT!
  1. ・エラー後の処理をアレンジしたい場合は、try-catch文を使おう!
  2. ・tryブロックでは、例外が起こり得る処理の実行が試みる!
  3. ・catchブロックでは、tryブロックで発生した例外を捕捉し、その後の処理を行う!

« »

カテゴリーリンク

著者について- author profile -

ROYDOプロフィール写真
Michihiro

モバイルアプリ(iOS・Android)ディベロッパー&デザイナー

これまでに、可読性の高いカラーパターンを自動で生成するアプリや、『第3火曜日』といった形式で通知をスケジュールできるアプリなどを制作。

サブでWebデザイン・フロントエンドエンジニアとしても活動しています。

📝ツール・言語:JavaScript/React Native/Kotlin/Android Studio/Swift/SwiftUI

🎓資格:基本情報技術者/ウェブデザイン技能検定3級

Twitterアイコン Instagramアイコン