?? Exception 異常插件

簡介
安裝
composer require tinywan/exception-handler
使用
配置
config/exception.php
return [
// 這里配置異常處理類
'' => \Tinywan\ExceptionHandler\Handler::class,
];
???? webman-admin 中配置
異常接管
/plugin/admin/config/exception.php
return [
'' => \Tinywan\ExceptionHandler\Handler::class,
];
接口不存在路由處理
/plugin/admin/config/route.php
Route::fallback(function () {
throw new \Tinywan\ExceptionHandler\Exception\RouteNotFoundException();
}, 'admin');
基本用法
請(qǐng)求參數(shù)錯(cuò)誤
use support\Request;
use support\Response;
use Tinywan\ExceptionHandler\Exception\BadRequestHttpException;
class Token{
public function issueToken(Request $request): Response
{
$params = $request->post();
if (empty($params)) {
throw new BadRequestHttpException('賬號(hào)或密碼不能為空');
}
}
}
以上異常拋出錯(cuò)誤信息,如下格式:
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=utf-8
{
"code": 0,
"msg": "賬號(hào)或密碼不能為空",
"data": {},
}
所有返回的異常信息將以json格式返回,以上為
返回簡略的異常信息
所有的異常錯(cuò)誤處理器根據(jù)配置文件 config/app.php
中debug
的值來調(diào)整錯(cuò)誤顯示, 當(dāng)debug
值為true
(表示在調(diào)試模式), 錯(cuò)誤處理器會(huì)顯示異常以及詳細(xì)的函數(shù)調(diào)用棧和源代碼行數(shù)來幫助調(diào)試,將返回詳細(xì)的異常信息。 當(dāng)debug
值為false
,只有錯(cuò)誤信息會(huì)被顯示以防止應(yīng)用的敏感信息泄漏,將返回簡略的異常信息。
返回詳細(xì)的異常信息
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=utf-8
{
"code": 0,
"msg": "password不允許為空",
"data": {
"request_url": "POST //127.0.0.1:8888/oauth/issue-token",
"timestamp": "2022-03-06 15:19:12",
"client_ip": "172.18.0.1",
"request_param": {
"username": "webman"
},
"error_message": "password不允許為空",
"error_trace": "#0 /var/www/webman-admin/app/functions.php(68): Tinywan\\Validate\\Validate->check(Array)\n#1 /var/www/webman-admin/app/controller/Authentication.php(25): ..."
}
}
如何自定義一個(gè)自己的異常類
編寫異常類
假設(shè)自定義一個(gè):405 Method Not Allowed
(表示:請(qǐng)求行中指定的請(qǐng)求方法不能被用于請(qǐng)求相應(yīng)的資源)
自定義異常類只需要繼承Tinywan\ExceptionHandler\Exception\BaseException
類即可
<?php
declare(strict_types=1);
namespace support\exception;
use Tinywan\ExceptionHandler\Exception\BaseException;
class MethodNotAllowedException extends BaseException
{
/**
* @var int
*/
public $statusCode = 405;
/**
* @var string
*/
public $errorMessage = '請(qǐng)求行中指定的請(qǐng)求方法不能被用于請(qǐng)求相應(yīng)的資源';
}
使用異常類
use support\Request;
use support\Response;
use support\exception\MethodNotAllowedException;
class Token{
public function issueToken(Request $request): Response
{
$params = $request->post();
if (empty($params)) {
throw new MethodNotAllowedException();
}
}
}
使用postman請(qǐng)求截圖
已支持插件異常類
- JWT 權(quán)限認(rèn)證插件 異常類
JwtTokenException
- Validate 驗(yàn)證器插件 異常類
ValidateException
內(nèi)置異常類
- 客戶端異常類(HTTP Status 400):BadRequestHttpException
- 身份認(rèn)證異常類(HTTP Status 401):UnauthorizedHttpException
- 資源授權(quán)異常類(HTTP Status 403):ForbiddenHttpException
- 資源不存在異常類(HTTP Status 404):NotFoundHttpException
- 路由地址不存在異常類(HTTP Status 404):RouteNotFoundException
- 請(qǐng)求限流在異常類(HTTP Status 429):TooManyRequestsHttpException
- 服務(wù)器內(nèi)部錯(cuò)誤異常類(HTTP Status 500):ServerErrorHttpException
HTTP 響應(yīng)狀態(tài)碼
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status
自定義異常 Response
只支持修改body
的三個(gè)字段的key值。必須保持順序是:
- ① 狀態(tài)碼
- ② 錯(cuò)誤消息
- ③ 響應(yīng)數(shù)據(jù)
使用場景
- 每個(gè)項(xiàng)目有標(biāo)準(zhǔn)的統(tǒng)一輸出,自定義返回內(nèi)容
- 前后端分離:前端要求返回的
HTTP狀態(tài)碼
并不是429
,而是200
或者其他- 響應(yīng)的
body
不是{"code":0,"msg":"Too Many Requests"}
,而是{"error_code":200,"message":"Too Many Requests"}
等其他內(nèi)容
自定義HTTP狀態(tài)碼
編輯 config/plugin/tinywan/exception-handler/app.php
文件的 status
HTTP 狀態(tài)碼
自定義body
返回內(nèi)容
編輯 config/plugin/tinywan/exception-handler/app.php
文件的 body
的字段
默認(rèn)選項(xiàng)是
{
"code": 0,
"msg": "Too Many Requests",
"data": null
}
自定義選項(xiàng)參考一
1、假設(shè)status
HTTP 狀態(tài)碼設(shè)置為 200
2、假設(shè)body
的數(shù)組設(shè)為為
'body' => [
'error_code' => 200,
'message' => '請(qǐng)求太多請(qǐng)稍后重試'
]
則響應(yīng)內(nèi)容為
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
{
"error_code": 200,
"message": "請(qǐng)求太多請(qǐng)稍后重試"
}
其他的可以根據(jù)自身業(yè)務(wù)自定義即可
擴(kuò)展自己的 Handler
當(dāng)項(xiàng)目需要自定義情況比較多的時(shí)候,很可能需要擴(kuò)展 Handler,此時(shí)可以繼承 Tinywan\ExceptionHandler\Handler
然后修改對(duì)應(yīng)方法即可。
使用場景
- response需要響應(yīng)
xml
,而不是json格式,只需要覆蓋buildResponse
方法- 擴(kuò)展其他Exception的響應(yīng),我只要覆蓋
solveExtraException
- 要異常推送微信消息,我可以覆蓋
triggerNotifyEvent
自定義異常 ErrorHandler
namespace support;
use Illuminate\Validation\ValidationException;
use Tinywan\ExceptionHandler\Handler;
use Webman\Http\Response;
class ErrorHandler extends Handler
{
/**
* @inheritDoc
*/
protected function solveExtraException(\Throwable $e): void
{
// 當(dāng)前項(xiàng)目下的異常擴(kuò)展
if ($e instanceof ValidationException) {
$this->errorMessage = $e->validator->errors()->first();
$this->errorCode = 422;
return;
}
parent::solveExtraException($e);
}
/**
* @inheritDoc
*/
protected function triggerNotifyEvent(\Throwable $e): void
{
// ... 這里省略觸發(fā)其他錯(cuò)誤推送渠道
parent::triggerNotifyEvent($e);
}
/**
* @inheritDoc
*/
protected function buildResponse(): Response
{
// 構(gòu)造自己項(xiàng)目下的響應(yīng)
return json([
'code' => $this->statusCode, // 使用 statusCode 作為 code 返回
'msg' => $this->errorMessage,
'data' => $this->responseData,
]);
}
}