www.bengo4.comPHPのエラーを理解して適切なエラーハンドリングを学ぶPHPerKaigi 20222022.4.9 namizato
View Slide
22並里 辰也(ナミザト タツヤ)自己紹介弁護士ドットコム株式会社 在籍そろそろ2年Laravelが好きだったけど2年位あまり追えてない最近はバスケばかりしてる@namizatork
Bengo4.com, Inc.● 一般市民と弁護士を結びつけ、お悩み解決を目指す● 2005年サービス開始● 利用者数 約1,000万人/ 月● 累計法律相談数 約100万件3弁護士ドットコムというサービスhttps://www.bengo4.com
Bengo4.com, Inc.弁護士ドットコムCreators’ Bloghttps://creators.bengo4.com最新の記事postcss-preset-envで少し未来のCSSを予習するデザイナーに優しいHTMLテンプレートの開発方針をボトムアップで作った話サービス運用10年以上の重み、弁護士ドットコムのユニットテスト速度改善弁護士ドットコムサービスのビジネスと共にみるマイクロサービスの進化4
Bengo4.com, Inc.目次● 今回の対象者と話す内容● エラーについて● エラーハンドリングについて● PHPの例外について● エラーハンドリングを学ぶ● 振り返り5
今回の対象者と話す内容6
Bengo4.com, Inc.今回の対象者と話す内容● 対象者○ エラーハンドリングという言葉は知ってるけど何をするの?という人○ PHPのエラー?とりあえずいつもググってるよ!という人● 話す内容○ エラーについて○ エラーハンドリングについて○ 適切なエラーハンドリング7
Bengo4.com, Inc.(一応)本内容での言葉を統一しておく● エラー(エラー処理)● エラーハンドリング(例外処理)● 例外(Exception)8
エラーについて9
Bengo4.com, Inc.エラーについて実行中のプログラムが正常に処理を続行できなくなるような問題・事態のこと。10
Bengo4.com, Inc.PHPのエラー● PHPのエラーは大きく分類して、致命的なエラー と 警告・注意 が存在する○ 致命的なエラー■ 現在の処理を中断する、はよ直せ(怒り)○ 警告・注意■ 現在の処理は中断しないけど、直した方がいいよ(ハナホジ)11
Bengo4.com, Inc.PHPの致命的なエラー / 警告・注意 を一部抜粋● 致命的なエラー○ Fatal error(存在しない関数を呼び出すなどで発生)○ Parse error(PHPの文法で間違いがあった時などで発生)● 警告・注意○ Warning(存在しないファイルを呼び出した時などで発生)○ Notice(定義されていない変数を使用した時などで発生)12
Bengo4.com, Inc. 13Warning や Notice は php.ini などの設定次第で無視(いわゆる白い画面のアレを表示しない)することは可能。バグの発生要因になるので、推奨はしない。
エラーハンドリングについて14
Bengo4.com, Inc.エラーハンドリングについてプログラムがエラーを起こした時にすぐに実行を終了せずにあらかじめ用意しておいた処理を行うこと。ユーザー操作によって解決できない問題があった場合に対処するための処理。15
Bengo4.com, Inc.PHPのエラーハンドリング5系から導入された try - catch で記述する。例外が発生し得る箇所を try {} で囲み、例外が発生した時点で後続する処理は中断され catch {} で受け取り、例外が発生した時の対応(ハンドリング)を行う。例外を明示的に(ほとんどはこのケースだと思うが)発生させたい場合は、該当する箇所で throw を用いる。16
Bengo4.com, Inc.PHPのエラーハンドリング書き方17
PHPの例外について18
Bengo4.com, Inc. 19実は前述した「PHPのエラー」で紹介した致命的なエラーなどの一部は try -catch で捕捉できません。(方法はあるにはある)ですが、大抵の場合それらを捕捉する必要はありません。次のページで簡単に PHP の例外について 触れながら説明していきます。
Bengo4.com, Inc.PHPの例外(Exception)5系までは、全ての致命的エラーはエラーハンドリングができず処理がそこで中断されてしまいます。しかし、7系からは Throwable インターフェースが実装され、それを継承した Exception と Error が導入されました。そのおかげで致命的エラーの多くが Error をスローするようになり、捕捉が可能になりました。右の図(by @ngyuki)は例外の継承関係を図にしたものです。20
Bengo4.com, Inc.PHPの例外(Exception)しかし、致命的なエラーの全てが Error に実装されたわけではないのが現状です。ですが、先述した通り全てを捕捉する必要はありません。大抵のエラーはプログラムやFW側が検知してくれているので、実装者は開発中に起きたエラーを修正するだけで済みます。そのためそれらをエラーハンドリングする必要はありません。21
エラーハンドリングを学ぶ22
Bengo4.com, Inc. 23エラーハンドリングというものについては少しは理解できたけど、必要性は?どういう時に使えばいいの?など疑問が残っていると思います。なので、一つ一つQ&A方式で説明していきます。
Q. エラーハンドリングを使わないとどうなるの?24
Bengo4.com, Inc.Q. エラーハンドリングを使わないとどうなるの?25Answer1. エラーの発生箇所や原因の特定が難しくなる2. エラー発生後も後続の処理が実行されてしまう3. エラーが起きていることをユーザーが認知できない詳しい説明は次の質問と繋がるので省きます。
Q. エラーハンドリングはどんな時に用いるの?26
Bengo4.com, Inc.Q. エラーハンドリングはどんな時に用いるの?27Answer1. エラーの発生箇所や原因の特定をしたい時2. エラー発生後に後続の処理を中断させて、別の対応をしたい時3. エラーが起きていることをユーザーに通知したい時
Bengo4.com, Inc.エラーの発生箇所や原因の特定をしたい時28例外が発生した内容を catch句 で受け取り、メッセージなどをロギングしておけば、発生箇所や発生日時、原因の特定が容易になる。
Bengo4.com, Inc.エラー発生後に後続の処理を中断させて、別の対応をしたい時29例外を受け取ったら処理は中断させて、別の対応をしたい時はロギングの時と同様にcatch句 の中で行いたい処理を書く。その際、return をしないと後続してしまうので注意!
Bengo4.com, Inc.エラーが起きていることをユーザーに認知したい時30こちらも先ほど同様に catch句 で例外を受け取ったら return で呼び出し元かユーザーにエラーを通知する。この対応が抜けているとユーザーは処理が問題なく対処されたと認識してしまう。
Q. エラーハンドリングを考えるうえで大事なことは?31
Bengo4.com, Inc.Q. エラーハンドリングを考えるうえで大事なことは?32Answer1. 例外を握り潰さない(物理的にではない)2. エラーハンドリングのスコープは狭く3. 補足すべき例外とそうでない例外を理解しよう
Bengo4.com, Inc.例外を握り潰さない33せっかく例外を throw しても catch句 で何もしなければエラーを無視してるも同然です。catch句 ではロギングの他にエラーの発生を呼び出し元に伝える、後続処理を行わないためにreturn するなど、要件に応じた対応をしましょう。
Bengo4.com, Inc.エラーハンドリングのスコープは小さく34様々な例外を全部一つの try {}の中におさめて、catch は全てException で拾ってしまっているtry {} の範囲が広いと例外が発生した時の特定が難しくなる。さらに catch句 は全て Exceptionで受け取るのではなく、それぞれ適切な例外クラスを用意して利用しましょう。
Bengo4.com, Inc.補足すべき例外とそうでない例外35● 補足すべき例外○ 例外発生以降も処理が続けられてしまうとデータ不整合など障害に繋がってしまう時○ 例外発生後に呼び出し元やユーザーへの通知、ロギングなどを行いたい時○ 例外発生前に行っている処理や状態をロールバックしたい時● 補足すべきでない例外○ 開発時に対処できるタイプエラーなどの例外○ 例外が発生しても、その後に回復処理などが行えない時
振り返り36
Bengo4.com, Inc.ここまで学んだエラーハンドリングを振り返る37基幹システムにユーザーとポイント情報をAPIでpostしているが、何らかのエラーになってもユーザーにはポイントが付与されたままになってしまう。
Bengo4.com, Inc.ここまで学んだエラーハンドリングを振り返る38基幹システムへのAPIで成功レスポンス(200)が返ってこなかった場合に、例外を throw して、ユーザーに対して付与していたポイントをロールバック。その後開発者向けにロギングと通知、リダイレクトしてユーザーにエラーがあって、ポイントを付与d系なかったことを伝える。
ご清聴ありがとうございました。39