1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

例外処理の対応(Laravel)

Last updated at Posted at 2023-09-02

はじめに

バックエンド側(API側)の処理で必要な処理だけを急いで書いて、エラー処理は疎かになりがちで、書いてもいつも書き方がまちまちなので、ここでいったん整理した。

記載方法

まとめたといっても単純でtry catchを使用することである。
特定の不具合に関してはエラー処理を具体的に決めて処理をするということである。

記載例

コントローラファイル
App\Http\Controllers

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Database\QueryException;
use PDOException;
use Exception;
use App\Exceptions\FileExtensionException;
use App\Exceptions\CsvColumnMismatchException;

class MyController extends Controller
{
    public function handleRequest(Request $request)
    {
        try {
            // ファイル拡張子の確認
            $this->validateFileExtension($request);

            // CSVファイルのカラム確認
            $this->validateCsvColumns($request);

            // トランザクションとDB操作
            $this->handleTransaction($request);  // $request を渡す

            return redirect()->route('success.page');

        } catch (FileExtensionException $e) {
            return back()->with('error', 'アップロードされたファイルはCSVではありません。');

        } catch (CsvColumnMismatchException $e) {
            return back()->with('error', 'CSVのカラムが一致しません。');

        } catch (PDOException $e) {
            return back()->with('error', 'データベースに接続できませんでした。');

        } catch (QueryException $e) {
            return back()->with('error', 'データベースクエリに問題がありました。');

        } catch (Exception $e) {
            \Log::error($e);  // 例外をログに記録
            return back()->with('error', 'データの操作中にエラーが発生しました。');
        }
    }

    private function validateFileExtension(Request $request)
    {
        if ($request->file('csv_file')->getClientOriginalExtension() !== 'csv') {
            throw new FileExtensionException();
        }
    }

    private function validateCsvColumns(Request $request)
    {
        // ここではサンプルとしてCSVの最初の行を取得し、カラムを確認します。
        $file = new \SplFileObject($request->file('csv_file')->path());
        $header = $file->fgetcsv();

        $expectedColumns = ['column1', 'column2', 'column3'];  // 期待されるカラム名のサンプル

        if ($header !== $expectedColumns) {
            throw new CsvColumnMismatchException();
        }
    }

    private function handleTransaction(Request $request)  // $request を引数として受け取る
    {
        // トランザクション開始
        DB::beginTransaction();

        try {
            // クエリ実行
            $result = DB::table('some_table')->get();

            // Eloquentモデルの保存
            $model = new MyModel;
            $model->some_field = $request->input('value');  // $request を使う
            $model->save();

            // トランザクションコミット
            DB::commit();

        } catch (Exception $e) {
            // トランザクションロールバック
            DB::rollback();
            throw $e;  // 例外を再スロー
        }
    }
}


例外ファイル
App\Exceptions

// FileExtensionException.php
namespace App\Exceptions;

use Exception;

class FileExtensionException extends Exception
{
    // 任意で追加のコード
}

// CsvColumnMismatchException.php
namespace App\Exceptions;

use Exception;

class CsvColumnMismatchException extends Exception
{
    // 任意で追加のコード
}

記載内容

Laravelを使用している。
csvファイルをアップしたのをテーブルに保存し、前画面に戻る例を挙げている。
エラーとして起こりうることとして色々あると思うが、何が起こるかを記載する。
今回は、エラーとして、ファイル拡張子、CSVファイルカラムのヘッダー確認を行なっている。
他に、ファイルの存在とアップロード確認、ファイルサイズ、csvのデータ行に対する検証等があるが、今回は割愛している。

要は何をエラーにするかを決めることである。

記載方法

1.本処理を書く。
ここではcsvアップとDB書き込みである。
必要に応じてメソッド化する(今回はメソッド化している)。

2.エラー処理をcatchで対応する。
既に存在する例外クラス、独自例外クラスは作成する。
ここが厄介なところかもしれない。

今回は以下既に存在する例外クラスを使用している。
useに記載する。

use Illuminate\Database\QueryException;
use PDOException;
use Exception;

これらの例外クラスは既に存在するので、useで記載する。
PDOExceptionは、PHPのPDO(PHP Data Objects)拡張で発生する可能性のあるエラーを表し、PHPの標準ライブラリに含まれています。
QueryExceptionは、LaravelのデータベースクエリビルダやEloquent ORMでデータベースクエリに関するエラーが発生した際に投げられる例外で、Laravelフレームワークに含まれる。

3.エラー処理作成
既存例外クラスは2で行う。
独自の例外クラスは、throw new クラス名()として対応。
そのクラスをApp¥Exceptionでフォルダを作成し、クラスを作成する。
今回はエラー状態を捕捉したいだけなので、例外クラスは空で構わない。
特定のエラー状態をプログラムが認識できるようになる。

その他

catch (Exception $e) で一般的なエラーをキャッチしているが、ここではエラーのロギングも行うといい。これによって、後でエラーを解析る。

おわりに

しばらくこれで様子を見る。
とりあえず例外を気にしない記載は控えていきたい。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?