JavaScriptでtry...catch構文を正しく使用する。

あとで読む

最初に

現在作成してるデスクトップアプリで受け取ったのが想定したURL以外の場合(空、ただの文字列、urlだけどアプリで使用しないURL例:goole.com等)に、エラー処理をしようと思ったので、JSのエラー処理について学んでみた。ただ正しくは例外処理と呼ぶらしい。記事を書きながら思ったのは上記の考え方でtry...catchを使用するのは少し違うと言う事です。

JSの例外処理(exception handling)はエラーが起きた時に適切な処理を行うための機構です。エラー処理ではなく「例外処理」と呼ばれるのは、想定しているエラーではなく、想定していない例外的なケースのための処理と言う意味です。

なので基本的にはディスク容量不足、ネットワークの不具合に使用されるのかな?

Errorオブジェクト

JSには組み込みのErrorオブジェクトがあり、エラー処理に利用出来ます。Errorのインスタンス生成時にエラーメッセージを指定することが出来ます。

const err = new Erroe('メールアドレスの形式が正しくありません');

このErrorインスタンスを生成するだけでは何も起こらない。

メールアドレスが正しいかどうかをチェックする関数を作ります。

function validateEmail(email) {
	return email.match(/@/)? /*三項演算子*/
		email: /* @が含まれる場合の戻り値 */
		new Error('無効なメールアドレスです:${email}');
}

???なんだ三項演算子って

if...elseのような条件から結果を出力出来る演算子だった。

今回の場合は email.match(/@/) で条件に一致つまり email の文字列に @ が含まれていれば True が返るため email が実行される。 console.log(email) とかにすれば分かりやすかった。ただの変数だとは email: と書いてあるから何か特殊な構文かと思った。 : が演算子だった。

偽の場合は new Error(無効なアドレスです:${email}); が実行される。

このように自主的にエラーオブジェクトを生成してエラーを発生させる事も出来るが、一般的な利用方法ではない。

try...catch構文

こちらを用いるのが一般的です。先ほどの関数を用いる。

function validateEmail(email) {
	return email.match(/@/)? /*三項演算子*/
		email: /* @が含まれる場合の戻り値 */
		new Error('無効なメールアドレスです:${email}');
}

const email = null;

try {
	const validatedEmail = validateEmail(email);
	const.log(validatedEmail);
	if(validatedEmail instanceof Error) {
		console.error(validatedEmail.message);
	} else {
		console.log(`正しい形式のアドレス:${validatedEmail}`);
	}
} catch(err) {
	console.error(`エラー:${err.message}`);
}

instanceof でインスタンスの状態を確認する。 validatedEmail にエラーオブジェクトが入っている場合は True を返す。

console.errorlogとほぼ同じだけどコンソールでエラーのような表示になる。 message にはエラーオブジェクトで生成された 無効なメールアドレスです:${email}); が格納されている。

catch ではハッカーが通常の文字列以外、 null や数字、あるいはオブジェクトを設定した場合にエラーとなります。このような予期しないものに対してcatchと挟みます。

Pythonとの違い

try...catch構文はなく

except にあらかじめ起こり得るエラー内容を想定して詳細に設定(下記のコードでは ZeroDivisionError ) して置かないといけない。Pythonでは全てのエラーに対して except する事を推奨していないためJSのような書き方が出来ない。

これも俗に言う宗派の違いだろうか...

def divide(x, y):
  try:
    print('%d/%d = %d' % (x, y, x/y))
  except ZeroDivisionError:
    print('ゼロ除算例外が発生しました。')

divide(6, 3)
divide(6, 0)

最後に

記事を書きながら思った。自分のケースでは例外処理と言うよりもまず先に条件式で詳細に縛りをいれた後にどうしても予期出来ないエラーをcatchするためにtry...catch構文を使用するんだと解釈に至った。 コンソールにエラーが出力されていたので、いきなり例外処理でなんとかしようと考えに至ったがどうやら甘い考えのようだ。

記事に関するコメント等は

🕊:Twitter 📺:Youtube 📸:Instagram 👨🏻‍💻:Github 😥:Stackoverflow

でも受け付けています。どこかにはいます。

参照

1)Ethan Brown. Learning JavaScript, 3rd Edition. O'Reilly. イーサン ブラウン ムシャ ヒロユキ ムシャ ルミ (訳) 2017. 「11章 例外とエラー処理」.『初めてのJavascript』. 第3版. オライリージャパン. pp 191-193.

Pythonの例外処理の基本try, exceptの使い方を現役エンジニアが解説【初心者向け】

JS唯一の三項演算子の使い方