Laravel 13 错误处理详解

摘要

Laravel 提供了强大的错误处理机制,包括异常处理和错误页面定制。本文将深入讲解 Laravel 13 的错误处理,包括:

  • 异常处理器配置
  • 自定义异常处理
  • 错误页面定制
  • 错误报告与日志
  • 实战案例与最佳实践

本文适合希望掌握错误处理的 Laravel 开发者。

1. 配置

1.1 错误处理配置

1
2
// config/app.php
'debug' => env('APP_DEBUG', false),

1.2 异常处理器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// app/Exceptions/Handler.php
<?php

namespace App\Exceptions;

use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Throwable;

class Handler extends ExceptionHandler
{
protected $dontFlash = [
'current_password',
'password',
'password_confirmation',
];

public function register(): void
{
$this->reportable(function (Throwable $e) {
// 自定义报告逻辑
});
}
}

2. 异常报告

2.1 report 方法

1
2
3
4
5
6
7
8
9
public function register(): void
{
$this->reportable(function (CustomException $e) {
// 发送到外部服务
if (app()->environment('production')) {
// 发送到 Sentry、Bugsnag 等
}
});
}

2.2 忽略异常

1
2
3
protected $dontReport = [
InvalidOrderException::class,
];

3. 异常渲染

3.1 render 方法

1
2
3
4
5
6
7
8
9
10
11
12
public function register(): void
{
$this->renderable(function (InvalidOrderException $e, Request $request) {
if ($request->expectsJson()) {
return response()->json([
'message' => $e->getMessage(),
], 400);
}

return redirect()->back()->with('error', $e->getMessage());
});
}

3.2 自定义异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php

namespace App\Exceptions;

use Exception;

class InvalidOrderException extends Exception
{
public function render()
{
return response()->json([
'message' => $this->getMessage(),
], 400);
}
}

4. 错误页面

4.1 自定义错误页面

1
2
3
4
5
resources/views/errors/
├── 404.blade.php
├── 403.blade.php
├── 500.blade.php
└── 503.blade.php

4.2 404 页面示例

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
<head>
<title>Page Not Found</title>
</head>
<body>
<h1>404 - Page Not Found</h1>
<p>Sorry, the page you are looking for could not be found.</p>
<a href="{{ url('/') }}">Go Home</a>
</body>
</html>

4.3 动态错误页面

1
2
3
4
5
6
7
8
9
10
11
12
13
// app/Exceptions/Handler.php
public function register(): void
{
$this->renderable(function (NotFoundHttpException $e, Request $request) {
if ($request->expectsJson()) {
return response()->json([
'message' => 'Resource not found',
], 404);
}

return response()->view('errors.404', [], 404);
});
}

5. 验证异常

5.1 验证异常处理

1
2
3
4
5
6
7
8
9
10
11
public function register(): void
{
$this->renderable(function (ValidationException $e, Request $request) {
if ($request->expectsJson()) {
return response()->json([
'message' => 'Validation failed',
'errors' => $e->errors(),
], 422);
}
});
}

6. 认证异常

6.1 认证异常处理

1
2
3
4
5
6
7
8
9
10
11
12
public function register(): void
{
$this->renderable(function (AuthenticationException $e, Request $request) {
if ($request->expectsJson()) {
return response()->json([
'message' => 'Unauthenticated',
], 401);
}

return redirect()->guest(route('login'));
});
}

7. 实战案例

7.1 API 错误处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<?php

namespace App\Exceptions;

use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Validation\ValidationException;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Throwable;

class Handler extends ExceptionHandler
{
public function register(): void
{
$this->renderable(function (ValidationException $e) {
return response()->json([
'success' => false,
'message' => 'Validation failed',
'errors' => $e->errors(),
], 422);
});

$this->renderable(function (ModelNotFoundException $e) {
return response()->json([
'success' => false,
'message' => 'Resource not found',
], 404);
});

$this->renderable(function (AuthenticationException $e) {
return response()->json([
'success' => false,
'message' => 'Unauthenticated',
], 401);
});

$this->renderable(function (NotFoundHttpException $e) {
return response()->json([
'success' => false,
'message' => 'Route not found',
], 404);
});

$this->renderable(function (Throwable $e) {
return response()->json([
'success' => false,
'message' => app()->environment('production')
? 'Server error'
: $e->getMessage(),
], 500);
});
}
}

8. 最佳实践

8.1 生产环境配置

1
2
3
// .env
APP_DEBUG=false
APP_ENV=production

8.2 错误报告

1
2
3
4
5
6
// 发送到外部服务
$this->reportable(function (Throwable $e) {
if (app()->environment('production')) {
// Sentry::captureException($e);
}
});

9. 总结

Laravel 的错误处理提供了完善的异常处理机制:

  1. 异常报告:灵活的报告配置
  2. 自定义渲染:自定义异常响应
  3. 错误页面:可定制的错误页面
  4. API 错误:统一的 API 错误格式

参考资料