煩惱:之前總是在控制器每個方法中重復寫try catch異常捕獲感覺非常繁瑣
// 之前寫的 偽代碼
class DemoController
{
public function test(Request $request) {
try{
// 業(yè)務邏輯
} catch (ValidationException $e) {
// 驗證器處理
} catch (ApiException $e) {
// 自定義異常處理
} catch (\Exception $e) {
// 系統(tǒng)異常處理
}
}
}
下面是修改之后的處理方式
第一步:
// 在support目錄下創(chuàng)建Exception.php
namespace support;
use Throwable;
use Webman\Http\Request;
use Webman\Http\Response;
use App\api\Exception\ApiException;
use Respect\Validation\Exceptions\ValidationException;
class Exception extends \Webman\Exception\ExceptionHandler
{
public function render(Request $request, Throwable $exception): Response
{
if ($exception instanceof ValidationException) {
// 驗證器異常處理
return json(['code'=>500, 'msg'=>$exception->getMessage()]);
}
if ($exception instanceof ApiException){
// 自定義異常處理
return json(['code'=>500, 'msg'=>$exception->getMessage()]);
}
if ($exception instanceof Throwable) {
// 記錄錯誤日志
Log::error($exception->getMessage());
return json(['code'=>500, 'msg'=>'系統(tǒng)異常']);
}
return parent::render($request, $exception); // TODO: Change the autogenerated stub
}
}
第二步:
// 修改config/exception.php配置文件
return [
// '' => support\exception\Handler::class,
'api' => support\Exception::class,
];
現(xiàn)在在控制器寫法偽代碼
class DemoController
{
public function test(Request $request) {
// 直接拋出異常
throw new ApiException('自定義異常');
}
}
我的
//控制器
public function getInfo(Request $request, AuthUserService $service): Response
{
try {
return json(['code' => RespConst::RESP_SUCCESS_CODE, 'msg' => RespConst::RESP_SUCCESS_TEXT, 'data' => $service->info($request)]);
} catch (WebmanException $e) {
return json(['code' => $e->getCode(), 'msg' => $e->getMessage(), 'data' => []]);
} catch (\Throwable $e) {
return json(RespConst::RESP_SERVICE_ERROR_MAP);
}
}
//manager
public function savePassword(Request $request): void
{
try {
ValidateFormTool::validator($request->post(), SavePasswordValidate::$rule, SavePasswordValidate::$message);
/** @var UserModel $model */
$model = $this->dao->findByAttribute(['uid' => $request->post('uid')])->getModel();
$model || throw new WebmanException('用戶不存在', RespConst::RESP_PARAMS_ERROR_CODE);
$model->passwordRule($request->post('password')) || throw new WebmanException(AuthConst::PWD_RULE_ERR_MSG, RespConst::RESP_PARAMS_ERROR_CODE);
$model->validatePassword($request->post('old_password')) || throw new WebmanException('`舊密碼`錯誤', RespConst::RESP_PARAMS_ERROR_CODE);
$this->dao->save(['password' => $request->post('password')]);
} catch (WebmanException $e) {
throw new WebmanException($e->getMessage(), intval($e->getCode()));
} catch (\PDOException | \Exception | \Error $e) {
throw new WebmanException(RespConst::RESP_SERVICE_ERROR_TEXT, RespConst::RESP_SERVICE_ERROR_CODE);
} catch (\Throwable $e) {
throw new WebmanException($e->getMessage(), RespConst::RESP_SERVICE_ERROR_CODE);
}
}
控制器轉發(fā)
manager業(yè)務服務
service基礎服務
dao數(shù)據(jù)處理
WebmanException 子定義,繼承Exception
\PDOException | \Exception | \Error 其它特殊異常
Throwable 兜底