Laravel仿Java对Exception统一处理
1332
2018-04-10
以Spring开发为例,通过ExceptionHandler,可以对业务中抛出的异常进行捕捉而后统一处理,避免了接口或页面对外暴露不友好的堆栈异常信息,规范了异常处理流程,并且减少了代码编写过程中额外的return。
Laravel已经预先定义了一些异常,如ModelNotFoundException、MassAssignmentException等,但是我们通常需要更业务化的定制以及更友好的异常处理流程,于是可以通过修改Laravel提供的Handler来满足需求。
Laravel的异常处理器在app/Exceptions/Handler.php文件中,一般只需要修改render()方法即可,如
/**
* Render an exception into an HTTP response.
*
* @param IlluminateHttpRequest $request
* @param Exception $exception
* @return IlluminateHttpResponse
*/
public function render($request, Exception $exception) {
// 仅捕捉指定类别的异常类型
if ($exception instanceof ArgumentValidationException
|| $exception instanceof BusinessException
|| $exception instanceof BusinessHttpException
|| $exception instanceof ObjectNotFoundException
) {
// 避免过多的堆栈信息,最多只输出5条
$publish_trace_length = count($exception->getTrace());
$publish_trace_length = $publish_trace_length >= 5 ? 5 : $publish_trace_length;
$traceArr = array_slice($exception->getTrace(), 0, $publish_trace_length);
// 对未定义异常码的异常进行Http Code转换
$exceptionCode = $exception->getCode() > 0 ? $exception->getCode() : 400;
// 以json形式输出异常
return response()->json([
'msg' => $exception->getMessage(),
'code' => $exception->getCode(),
'detail' => $traceArr
], $exceptionCode);
} else {
return parent::render($request, $exception);
}
}
然后具体业务异常的定义可以在任意目录(通常在app/Exceptions)下,具体定义如:
/**
* 参数异常
* Class BusinessHttpException
* @package SymfonyComponentHttpKernelException
*/
class ArgumentValidationException extends HttpException {
public static $http_code = 400;
/**
* Constructor.
*
* @param string $message The internal exception message
* @param Exception $previous The previous exception
* @param int $code The internal exception code
*/
public function __construct($message = null, $code = 0, Exception $previous = null) {
parent::__construct(self::$http_code, $message, $previous, array(), $code);
}
}
于是在业务中我们可以直接throw new ArgumentValidationException('异常内容')即可。