Laravel エラーハンドリング
投稿日:2026/02/06
本記事では、Laravelのエラーハンドリングを整理し、設計 → 実装例 → よくあるアンチパターンの順で解説します。
Laravelのエラーハンドリング
Laravelでは主に以下でエラーを扱います。
| 役割 | 場所 |
|---|---|
| 例外の定義 | Exception クラス |
| 例外の捕捉・変換 | app/Exceptions/Handler.php |
| ログ出力 | config/logging.php |
| エラー画面 | Blade / JSONレスポンス |
👉 「例外を投げる」と「どう返すか」は分離されている のが重要ポイントです。
例外とエラーの違いを整理する
PHPエラー
- 文法エラー
- 未定義変数
- 型エラー
👉 基本的に開発時に修正するもの
Laravelで扱う例外(Exception)
- データが存在しない
- 権限がない
- 想定外の状態
👉 業務ロジック上の異常
よく使うLaravel標準例外
Laravelには最初から便利な例外が用意されています。
| 例外 | 用途 |
|---|---|
ModelNotFoundException |
データが見つからない |
AuthorizationException |
権限エラー |
ValidationException |
バリデーションエラー |
HttpException |
HTTPエラー全般 |
Controllerでの基本的なエラーハンドリング
❌ 悪い例(ifだらけ)
if (!$user) {
return redirect()->back()->withErrors('ユーザーが存在しません');
}
⭕ 良い例(例外に任せる)
$user = User::findOrFail($id);
👉 例外はLaravelに任せる
独自例外を作成する
例:業務エラー用例外
php artisan make:exception BusinessException
class BusinessException extends Exception
{
}
使用例
if ($order->isExpired()) {
throw new BusinessException('この注文は期限切れです');
}
👉 業務ルール違反は独自例外で表現すると可読性が上がる
Handler.php で一元管理する
app/Exceptions/Handler.php
public function render($request, Throwable $e)
{
if ($e instanceof BusinessException) {
return response()->view('errors.business', [
'message' => $e->getMessage()
], 400);
}
return parent::render($request, $e);
}
👉 try-catch を各所に書かなくて済む
API向けエラーハンドリング
APIでの基本方針
- HTTPステータスコードを正しく使う
- エラー形式を統一する
例:JSONエラーレスポンス
if ($request->expectsJson()) {
return response()->json([
'message' => $e->getMessage(),
'error_code' => 'BUSINESS_ERROR'
], 400);
}
バリデーションエラーの扱い
FormRequestを使う
class StoreUserRequest extends FormRequest
{
public function rules()
{
return [
'email' => 'required|email',
];
}
}
👉 ValidationExceptionはLaravelが自動処理
ログ設計
ログレベルの使い分け
| レベル | 用途 |
|---|---|
| debug | 開発用 |
| info | 正常処理の記録 |
| warning | 軽微な異常 |
| error | 明確なエラー |
| critical | 即対応レベル |
例外時のログ
report($e);
👉 ログは「調査できる粒度」で残す
本番環境での注意点
.env
APP_ENV=production
APP_DEBUG=false
👉 本番でスタックトレースは絶対に出さない
よくあるアンチパターン
❌ try-catchの乱用
try {
...
} catch (\Exception $e) {
return null;
}
👉 エラー時に何もしないのが一番危険
❌ 例外メッセージをそのままユーザー表示
- 内部構造が漏れる
- セキュリティリスク
👉 表示用メッセージとログは分ける
実務でおすすめの設計方針
- 例外は「異常状態の表現」
- 制御フローに使わない
- Handlerで集約
- API / Web で返却形式を分ける
- ログを必ず残す
まとめ
Laravelのエラーハンドリングは、
- 例外を正しく投げる
- Handlerで一元管理
- ログとユーザー表示を分離
この3点を守るだけで、 保守性・可読性・安全性が一気に向上 します。