Slide 1

Slide 1 text

楽しく向き合う例外対応 おくつ #phpcon_nagoya 1

Slide 2

Slide 2 text

$whoami = [ '名前' => 'おくつ', '所属' => '株式会社カオナビ', '職種' => 'バックエンドエンジニア', '特技' => '暮らし', '一言' => 'スイカが好きです', ]; #phpcon_nagoya 自己紹介 2

Slide 3

Slide 3 text

本番環境の例外対応をした経験ありますか? 楽しかったですか? 以降は、Laravel で構築されたアプリケーションにおける 例外の話をします。 #phpcon_nagoya 3

Slide 4

Slide 4 text

Laravel(11.x) では、 アプリケーション内の例外を bootstrap/app.php の withExceptions メソッドを使用して、 例外をどのように報告するかを管理できます。 以降ではアプリケーション内での例外について、 通知したい例外クラスのみ Slack の特定チャンネルで報告している前提としたいと思います。 #phpcon_nagoya Laravel における例外管理(Exception ) 4

Slide 5

Slide 5 text

報告 原因 調査 / 再現確認 報告 対応 振り 返り 報告 検知 対応 検討 #phpcon_nagoya 対応の流れ 5

Slide 6

Slide 6 text

#phpcon_nagoya 検知 6

Slide 7

Slide 7 text

まずは第一報を上げる 原因は分からないが、何かが発生していることを周知することで 関係者の確認コストが減ります。 発生日時 影響範囲( 対象ユーザ・機能) 事象 #phpcon_nagoya 報告 7

Slide 8

Slide 8 text

具体的なエラーメッセージやスタックトレースを確認 直近のデプロイや設定変更の確認 #phpcon_nagoya 原因の確認 8

Slide 9

Slide 9 text

エラー内容から、 直近のデプロイや設定変更の影響であることが明らかな場合、 戻します。 #phpcon_nagoya 原因の確認 9

Slide 10

Slide 10 text

エラーを再現していきます。 手がかりを集め、 条件や再現手順を特定します。 ( 名探偵になった気持ちで) #phpcon_nagoya 原因調査および再現確認 10

Slide 11

Slide 11 text

データの問題であるというエラーの場合、 データベースの値を確認をします。 そのデータの状態があり得るのか、 何者かによって変更されたのか判断します。 #phpcon_nagoya 原因調査および再現確認 11

Slide 12

Slide 12 text

時系列で事象を整理 単発の操作では再現できないとき 前後のアクセスログを時系列で並べ てみます。 #phpcon_nagoya 原因調査および再現確認 12

Slide 13

Slide 13 text

開発環境では再現できないな 本番環境と開発環境の違いによる影響を考えます。 たとえば、 キャッシュの仕組みが異なる データベースの構成が異なる など #phpcon_nagoya 原因調査および再現確認 13

Slide 14

Slide 14 text

( ※注意:叫ぶ場所は選ぶこと) #phpcon_nagoya 開発環境で再現できました! 14

Slide 15

Slide 15 text

回避方法の検討をします。 もし、修正がすぐにできなかったとしても 回避する方法を用いて ユーザの目的が達成できるのであれば それを考えてみます。 #phpcon_nagoya 対応検討 15

Slide 16

Slide 16 text

コードに問題があるのであれば、修正方法を検討します。 #phpcon_nagoya 対応検討 16

Slide 17

Slide 17 text

ユーザにとってより良くて、 かつ通知が来ない方法がないかという別の観点を考えてみます。 データがなかった場合 ユーザ入力値に問題がある場合( もしくは不正なリクエスト) ユーザ操作には影響させなくてよい場合 #phpcon_nagoya 対応検討 17

Slide 18

Slide 18 text

データがなかった場合 元 $user = User::find($id); return response()->json([ 'id' => $user->id; // $userがnullの時、ここでエラーになる ]); #phpcon_nagoya 対応検討 18

Slide 19

Slide 19 text

データがなかった場合 こうする $user = User::find($id); if (!$user) { // データが存在することをチェックする throw new NotFoundHttpException('該当のユーザは見つかりませんでした。'); } return response()->json(['id' => $user->id;]); ※ Laravel は、あらかじめいくつかのタイプのエラーを無視しています。NotFoundHttpException は無視 されています。 #phpcon_nagoya 対応検討 19

Slide 20

Slide 20 text

ユーザ入力値に問題がある場合( もしくは不正なリクエスト) 元 $user_name = $request->input('user_name'); // usersテーブルのnameにNOT NULL 制約あり User::create(['name' => $user_name]); リクエストの 'user_name'  がnull の時... #phpcon_nagoya 対応検討 20

Slide 21

Slide 21 text

ユーザ入力値に問題がある場合( もしくは不正なリクエスト) こうする // バリデーションで弾かれた場合、ValidationException $request->validate([ 'user_name' => 'required|string|min:3|max:20', ]); $user_name = $request->input('user_name'); User::create(['name' => $user_name]); ※ レスポンスを受け取る側で、エラーメッセージを表示する仕組みを作る必要があります。 #phpcon_nagoya 対応検討 21

Slide 22

Slide 22 text

ユーザ操作には影響させなくてよい場合 たとえばログ通知の失敗とか、特定のオプション機能の失敗など class MyCustomValidationException extends Exception try { // 何か処理 } catch (MyCustomValidationException $e) { // 独自例外のみ捕捉し、何かする } // その他の例外はそのままthrow #phpcon_nagoya 対応検討 22

Slide 23

Slide 23 text

発生日時 影響範囲( 対象ユーザ・機能) 事象 原因 回避方法 対応目処 #phpcon_nagoya 報告 23

Slide 24

Slide 24 text

伝わる言葉でユーザの知りたいことを報告します。 ユーザが知りたい情報は、 自分にどんな影響があるのか どうすれば解決できるのか、あるいは待つしかないのか #phpcon_nagoya 報告 24

Slide 25

Slide 25 text

対応が完了したら、完了報告します。 #phpcon_nagoya 対応  →  完了報告 25

Slide 26

Slide 26 text

人への責任のなすりつけ合いではなく、 再発防止に目を向けましょう。 ノーム・カースの最優先条項 今日見つけたものが何であれ、 チームの全員が、その時点でわかっていたことや スキルおよび能力、利用可能なリソースを余すことなく使って、 置かれた状況下でベストを尽くした、ということを疑ってはならない。 #phpcon_nagoya 振り返りをしよう https://scrapbox.io/iki-iki/ ノーム・カースの最優先条項 26

Slide 27

Slide 27 text

例外通知対応があるなんて、 ユーザが使っている証拠だからありがたいですね 楽しく、冷静に、そしてユーザ視点で対応していきましょう! #phpcon_nagoya まとめ 27

Slide 28

Slide 28 text

ご清聴ありがとうございました #phpcon_nagoya 28