Errorオブジェクトを知ろう

普段、書いたコードが上手くいかないときは、Errorの内容を見て、どこでつまづいているのか、”debugger”を入れたり、怪しいところでconsole.logしてみたりする。しかし、Error自体をハンドルするのはこれまであまり意識的にやってこなかったことに気がついた。まるで近所のスーパーの店員さんみたいな存在!?毎日のように見かけるし、お世話になっているのに名前も知らない・・・

Errorはオブジェクト

実行時エラーが発生すると、新しいErrorオブジェクトが生成され、throwされる。

一つずつゆっくり見ていこう。
まず、大事なポイントは「Errorオブジェクトが生成される」という部分。
クラスモジュールの勉強でやったConstructorを使ってオブジェクトを生成するのだが、すでにその辺は色々用意されているので、簡単にErrorオブジェクトが作れてしまう。

JavaScript
new Error()

例えば、以下のように表示させたいエラーメッセージを()の中に書くこともできる。
console.logをconsole.errorとすれば、Errorのスタイルで表示される。

newError

でも普段、エラーって勝手に出てくるよね?

自動的に生成されるError

その通り!自動的にErrorオブジェクトが作られるし、エラーの種類まで判別して教えてくれることがある。

ReferenceError: XXX is not defined とか
SyntaxError: Unexpected token XXX とか。

こういうのは、またそれぞれコンストラクターが別で存在し、new ReferenceError()とか new SyntaxError()と書けば同様にErrorオブジェクトを簡単に生成できるようになっている。
他にも数字しか入れられないところに文字列を入れた時のTypeErrorや、無限ループに陥った時などに発生するRangeErrorなどがある。

自動的に生成されないError

だとすると、特に自分でErrorを生成しなくてもいいような気がするが、APIからのデータ取得に失敗した場合にErrorハンドリングをしているのはなぜだろう。

Errorオブジェクトが自動で生成されるかどうかは、エラーの発生原因によるらしい。
JavaScriptコード内で発生する一般的なエラー、例えばゼロでの割り算や定義していない変数の使用など、実行時エラーが発生した場合、JavaScriptエンジンは自動的にErrorオブジェクトを生成してErrorをthrowする。
一方でAPIからのデータ取得に失敗した場合など、JavaScriptコードの外でエラーが発生し、それをただ受け取ってしまったような場合は、Errorオブジェクトは自動的にthrowされない。その代わりに、HTTPステータスコードやネットワークレベルのエラーが返ってきているはずなので、その情報(ここではresponse.okを使用)をもとに開発者がif〜やcatchなどを使ってエラーハンドリングを行う必要がある。

JavaScript
fetch('https://api.example.com/data')
  .then(response => {
    if (!response.ok) {
      throw new Error('APIからデータを取得できませんでした');
    }
    return response.json();
  })
  .then(data => {
    // データの処理
  })
  .catch(error => {
    console.error('エラーが発生しました:', error.message);
  });

Memo:
fetch() から返されるプロミスは、レスポンスが HTTP 404 や 500 を返す HTTP エラーステータスの場合でも拒否されません。サーバーがヘッダーで応答すると、プロミスは直ちに正常に解決します(レスポンスが 200-299 の範囲にない場合は、レスポンスの ok プロパティが false に設定されます)。拒否されるのは、ネットワーク障害があった場合や、何かがリクエストの完了を妨げた場合のみです。(MDNより抜粋)
そのため、responseがokではなかった時、throw new Error() をしてErrorを生成している。このErrorは、 catchされconsoleに表示される。

Uncaught (unhandled error)

話が前後するが、エラーが自動的に生成される場合も実は何もしなくていいというわけではない。try & catchをしてErrorハンドリングするように努めなくてはいけない。ハンドルされていないエラーが発生すると、プログラムは予期しない状態に陥り異常終了したり、安定性が損なわれる可能性がある。
実はconsoleでErrorが”Uncaught(捕まってない)”で始まっていたら、これはError handlingされていないエラーが出てきたという意味。こういうものが本番環境で出ないように適切な対応方法を指定しておかなければならない。

uncaught

Errorメッセージは誰のため?

ところで new Error(“ここに書くエラーメッセージは誰に向けて書くのか”)
Webアプリなどが動かない原因をそのアプリなどを使っているユーザーに向けて、分かりやすく伝えるために書くわけではないことに注意しなければならない。特にエラーの中に機密情報(セキュリティー情報や個人情報等)が含まれないように注意する必要がある。
Errorオブジェクトは開発者自身のためのものなので、デバッグ等のためにどういうエラーかがわかれば良い。

そうは言っても「あなたのお探しのXXXは見つかりませんでした」とか、「写真のサイズが大きすぎます」とか、「パスワードが間違っています」とか。ユーザー向けのエラーハンドリングも必要になる場合も多いので、Error()をthrowするのと並行して、他のページにリダイレクトしたり、別の形でメッセージを出すなど、ユーザー向けに分かりやすいフォローを入れることも考えなければいけない。

それでは今日はここまで!


ITパスポートを今度受けてみようと思って
イラスト多めの参考書を買った。
確かに分かりやすかったのだが
昨日読み終わって、いざ過去問にチャレンジしたら
参考書を見返してもやっぱりどこにも書いていないぞ!?
という問題が多くてこの本だけで大丈夫か若干不安になってる🙄

ITPassportBook

類似投稿