Handler.php
4.68 KB
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<?php
namespace App\Exceptions;
use App\Helpers\JsonResource;
use App\Support\BusinessCode;
use Hikoon\LaravelApi\Exceptions\ValidationException;
use Hikoon\LaravelApi\Support\ApiCode;
use Hikoon\LaravelApi\Support\ApiResponse;
use Hikoon\LaravelJwt\Exceptions\TokenExpiredException;
use Hikoon\LaravelJwt\Exceptions\TokenInvalidException;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\Exceptions\ThrottleRequestsException;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Arr;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Throwable;
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that are not reported.
*
* @var array<int, class-string<\Throwable>>
*/
protected $dontReport = [
ValidationException::class,
TokenExpiredException::class,
UserStatusException::class
];
/**
* Register the exception handling callbacks for the application.
*
* @return void
*/
public function register(): void
{
$this->reportable(static function (Throwable $e) {
});
}
/**
* @param $request
* @param \Throwable $e
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response|\Symfony\Component\HttpFoundation\Response
* @throws \Hikoon\LaravelApi\Exceptions\ValidationException
* @throws \Throwable
*/
public function render($request, Throwable $e): \Illuminate\Http\Response|JsonResponse|Response
{
if ($e instanceof \Illuminate\Validation\ValidationException) {
throw new ValidationException(ApiCode::VALIDATION_ERROR, $e->getMessage());
}
if ($e instanceof UserStatusException) {
throw new AuthenticationException('账号已被禁用/注销');
}
return parent::render($request, $e);
}
/**
* @param $request
* @param \Throwable $e
* @return \Illuminate\Http\JsonResponse
*/
protected function prepareJsonResponse($request, Throwable $e): JsonResponse
{
if ($request->is('manage/*') || $request->is('admin/*') || $request->is('user/*')) {
return match (true) {
$e instanceof \Illuminate\Validation\ValidationException => ApiResponse::fail(ApiCode::VALIDATION_ERROR, $e->getMessage()->errors()->first()),
$e instanceof TokenExpiredException, $e instanceof TokenInvalidException => ApiResponse::fail(BusinessCode::AUTHORIZED_EXPIRED_ERROR),
$e instanceof HttpException && $e->getStatusCode() === 503 => ApiResponse::fail(ApiCode::SERVICE_UNAVAILABLE_ERROR),
$e instanceof NotFoundHttpException => ApiResponse::fail(ApiCode::NOT_FOUND_ERROR),
$e instanceof MethodNotAllowedHttpException => ApiResponse::fail(ApiCode::METHOD_NOT_ALLOWED_ERROR),
$e instanceof ThrottleRequestsException => ApiResponse::fail(ApiCode::REQUEST_LIMIT_ERROR),
default => ApiResponse::make(Arr::except($this->convertExceptionToArray($e), 'message'))->toFail(ApiCode::SERVICE_ERROR)
};
}
if ($request->is('app/*')) {
return match (true) {
$e instanceof TokenExpiredException, $e instanceof TokenInvalidException => JsonResource::unauthenticated(JsonResource::AUTHORIZED_EXP),
$e instanceof MethodNotAllowedHttpException => JsonResource::fail('无效的请求方式'),
$e instanceof ThrottleRequestsException => JsonResource::fail('请求太频繁,请稍后再访问'),
$e instanceof NotFoundHttpException => JsonResource::fail('无法找到对应资源'),
default => JsonResource::error('服务器繁忙,请稍后再尝试...')
};
}
return parent::prepareJsonResponse($request, $e);
}
/**
* @inheritDoc
*/
protected function unauthenticated($request, AuthenticationException $exception): Response
{
if ($request->acceptsJson()) {
if ($request->is('manage/*') || $request->is('admin/*') || $request->is('user/*')) {
return ApiResponse::fail(ApiCode::UNAUTHORIZED_ERROR, $exception->getMessage())->setStatusCode(401);
}
if ($request->is('app/*')) {
return JsonResource::unauthenticated($exception->getMessage() ?? JsonResource::UNAUTHORIZED);
}
}
return parent::unauthenticated($request, $exception);
}
}