Slide 1

Slide 1 text

Laravel 5.6 デフォルトの 例外ハンドリング処理を まとめてみた Laravel/Vue.js 勉強会 #4

Slide 2

Slide 2 text

#laravue ですが 今回は Laravel オンリーの おなはしです おことわり

Slide 3

Slide 3 text

岡田 正平(おかだ しょうへい)@okashoi • 株式会社ウィルゲート 2015年新卒入社 • 開発室 ソリューションユニット 所属 • PHP, Laravel, Vue.js 3 自己紹介 Slides:

Slide 4

Slide 4 text

Laravel 5.6 にて • エラー発生時に所定のフォーマットでログを出力したい • エラー発生時に所定の slack チャネルに通知を送りたい • エラー画面のメッセージとログに出力するメッセージを分けたい 4 (背景)やりたかったこと

Slide 5

Slide 5 text

5

Slide 6

Slide 6 text

(アプリケーション内で)catch されなかった例外に対する処理を App¥Exceptions¥Handler に記述すればよさそう • report: ロギングに関する設定 • render: どのようなレスポンスを返すかの設定 > All exceptions are handled by the App¥Exceptions¥Handler class. This class contains two methods: report and render. (中略) The report method is used to log exceptions or send them to an external service like Bugsnag or Sentry. (中略) The render method is responsible for converting a given exception into an HTTP response that should be sent back to the browser. 6

Slide 7

Slide 7 text

よっしゃ、設定するぜ! .

Slide 8

Slide 8 text

よっしゃ、設定するぜ! . ……

Slide 9

Slide 9 text

Slide 10

Slide 10 text

• エラーの種類によってログが出力されたりされなかったり、 どうやって実現しているの? • 結局どのエラーがログ出力されないの? • したときは report されるの? • バリデーションエラーのときの挙動はどうやって実現しているの? 10 ところで、デフォルトでは何をやってるのよ? abort()

Slide 11

Slide 11 text

まとめてみた

Slide 12

Slide 12 text

1. 指定された例外については何もせずに終了 • カスタマイズ可能な App¥Exceptions¥Hander の $dontreport に加え 基底クラス Illuminate¥Foundation¥Exceptions¥Handler には $internalDontReport 2. 例外自信が report() メソッドを持っていたら 優先的にそちらの処理を行って終了 3. それ以外は $logger->error() でログ出力 12 のデフォルトの挙動 report() protected $internalDontReport = [ AuthenticationException::class, AuthorizationException::class, HttpException::class, HttpResponseException::class, ModelNotFoundException::class, TokenMismatchException::class, ValidationException::class, ]; report()

Slide 13

Slide 13 text

1. 指定された例外については何もせずに終了 • カスタマイズ可能な App¥Exceptions¥Hander の $dontreport に加え 基底クラス Illuminate¥Foundation¥Exceptions¥Handler には $internalDontReport 2. 例外自信が report() メソッドを持っていたら 優先的にそちらの処理を行って終了 3. それ以外は $logger->error() でログ出力 13 のデフォルトの挙動 report() protected $internalDontReport = [ AuthenticationException::class, AuthorizationException::class, HttpException::class, HttpResponseException::class, ModelNotFoundException::class, TokenMismatchException::class, ValidationException::class, ]; report()

Slide 14

Slide 14 text

• の中身は HttpException を送出しているだけ • artisan down によるメンテナンスモードのときは投げられた例外が 最終的に ServiceUnavailableHttpException に変換される ➢ 結果、どちらも report されない 14 のデフォルトの挙動 report() report() abort() ※スペースの都合上、名前空間は省略

Slide 15

Slide 15 text

1. 例外自身が render 可能なら優先的にそちらを利用して終了 2. 特定の例外を変換 3. 特定の例外については専用の処理を行って終了 例) ValidationException → json レスポンスならエラーレスポンスを返す そうでなければ前の画面にリダイレクト 4. json レスポンスならエラーレスポンスを返す or デバッグモードなら詳細表示 or 例外を HttpException に変換してエラー画面を描画 15 のデフォルトの挙動(ざっくり) report() render() ※スペースの都合上、名前空間は省略

Slide 16

Slide 16 text

1. 例外自身が render 可能なら優先的にそちらを利用して終了 2. 特定の例外を変換 3. 特定の例外については専用の処理を行って終了 例) ValidationException → json レスポンスならエラーレスポンスを返す そうでなければ前の画面にリダイレクト 4. json レスポンスならエラーレスポンスを返す or デバッグモードなら詳細表示 or 例外を HttpException に変換してエラー画面を描画 16 のデフォルトの挙動(ざっくり) report() render() ※スペースの都合上、名前空間は省略 protected function prepareException(Exception $e) { if ($e instanceof ModelNotFoundException) { $e = new NotFoundHttpException($e->getMessage(), $e); } elseif ($e instanceof AuthorizationException) { $e = new AccessDeniedHttpException($e->getMessage(), $e); } elseif ($e instanceof TokenMismatchException) { $e = new HttpException(419, $e->getMessage(), $e); } return $e; }

Slide 17

Slide 17 text

1. 例外自身が render 可能なら優先的にそちらを利用して終了 2. 特定の例外を変換 3. 特定の例外については専用の処理を行って終了 例) ValidationException → json レスポンスならエラーレスポンスを返す そうでなければ前の画面にリダイレクト 4. json レスポンスならエラーレスポンスを返す or デバッグモードなら詳細表示 or 例外を HttpException に変換してエラー画面を描画 17 のデフォルトの挙動(ざっくり) report() render() ※スペースの都合上、名前空間は省略 →バリデーションエラーのときに 「よしなに」やってくれる挙動は render によるもの

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

• エラー発生時に所定のフォーマットでログを出力したい • エラー発生時に所定の slack チャネルに通知を送りたい • エラー画面のメッセージとログに出力するメッセージを分けたい 19 やりたかったことへの解 report の設定はいじる必要なし logging の errorlog channel をカスタマイズ ログ出力したいエラーに abort は使わない

Slide 20

Slide 20 text

• エラー発生時に所定のフォーマットでログを出力したい • エラー発生時に所定の slack チャネルに通知を送りたい • エラー画面のメッセージとログに出力するメッセージを分けたい 20 やりたかったことへの解 エラー画面用メッセージをプロパティとして持った独自例外を定義 render でそのメッセージが表示されるように記述する ※スペースの都合上、名前空間は省略