---
## 1. 如何自定義 laravel 的業務異常
#### 編寫 `CodeResponse` 常量異常和狀態碼
> 首先我們要明確如何規定異常狀態碼
-401 參數值不合法
-402 參數值不對
-1 成功
-1 失敗
#### 參考狀態
const SUCCESS = [1, '成功'];
const FAIL = [-1, ''];
const PARAM_ILLEGAL = [401, '參數不合法'];
const PARAM_VALUE_ILLEGAL = [402, '參數值不對'];
## 2. 創建 BusinessException

#### 重寫構造方法
namespace App\Exceptions;
use Exception;
class BusinessException extends Exception
{
public function __construct(array $codeResponse, $info = '')
{
list($code, $message) = $codeResponse;
parent::__construct($info ?: $message, $code);
}
}
#### 添加 Handler 中的 `render` 方法把異常進行統一格式化
/**
* Render an exception into an HTTP response.
* @param \Illuminate\Http\Request $request
* @param \Throwable $exception
* @return Response
*
* @throws \Throwable
*/
public function render($request, Throwable $exception)
{
//validation Exception Unified processing and formatting
if($exception instanceof ValidationException){
return response()->json([
'errno' => CodeResponse::PARAM_VALUE_ILLEGAL[0],
'errmsg' => CodeResponse::PARAM_VALUE_ILLEGAL[1],
]);
}
//Business Exception Unified processing and formatting
if ($exception instanceof BusinessException) {
return response()->json([
'errno' => $exception->getCode(),
'errmsg' => $exception->getMessage()
]); //格式化成json
}
return parent::render($request, $exception);
}
#### 載入異常類到 `Handler`
protected $dontReport = [
BusinessException::class
];
## 3. 把異常處理方法統一放到公共父類控制器中
class BlogController extends Controller
{
/**
* @param array $codeResponse
* @param null $data
* @param string $info
* @return JsonResponse
*/
protected function codeReturn(array $codeResponse, $data = null, $info = '')
{
list($errno, $errmsg) = $codeResponse;
$ret = ['errno' => $errno, 'errmsg' => $info ?: $errmsg];
if (!is_null($data)) {
if(is_array($data)){
$data = array_filter($data, function ($item){
return $item !== null;
});
}
$ret['data'] = $data;
}
return response()->json($ret);
}
/**
* @param null $data
* @return JsonResponse
*/
protected function success($data = null)
{
return $this->codeReturn(CodeResponse::SUCCESS, $data);
}
/**
* @param array $codeResponse
* @param string $info
* @return JsonResponse
*/
protected function fail(array $codeResponse = CodeResponse::FAIL, $info = '')
{
return $this->codeReturn($codeResponse, null, $info);
}
/**
* @param $isSuccess
* @param array $codeResponse
* @param null $data
* @param string $info
* @return JsonResponse
*/
protected function failOrSuccess(
$isSuccess,
array $codeResponse = CodeResponse::FAIL,
$data = null,
$info = ''
) {
if($isSuccess){
return $this->success($data);
}
return $this->fail($codeResponse, $info);
}
}
## 4. 如何使用我們自定義的異常類
#### 部署路由, 我們建立一個 `blog.php` , 這里我們暫時先不用權限認證和jwt來校驗
Route::post('auth/login','AuthController@login'); //賬號登錄
#### 注入路由服務 `RouteServiceProvider`
protected $namespace = 'App\\Http\\Controllers'; //這里需要打開由于原來是注釋的情況
public function boot()
{
$this->configureRateLimiting();
$this->routes(function () {
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
Route::prefix('blog') //這里是我們新加的
->namespace($this->namespace.'\Blog')
->group(base_path('routes/blog.php'));
});
}
#### 編寫控制器方法
class AuthController extends BlogController
{
public function login()
{
return $this->success('');
}
}
#### 編寫測試文件

> #### 注意我們這里的命令空間, 測試成功返回
Time: 00:04.932, Memory: 22.00 MB
OK (1 test, 1 assertion)
## 5. 瀏覽器查看
#### 因為是 post 請求所以我們改變規則(方便測試,后期涉及到安全方面的都需要 any)
Route::any('auth/login','AuthController@login'); //賬號登錄

#### 格式化用 chome 的 json 插件
## 使用 postman 進行測試。 效果是一樣的我這里就不演示了
---
## 總結
> #### 以上我們就對 laravel8.5 版本進行了一次異常業務和測試的封裝, 該項目是: [laravel 8 + angular + markdown ](https://github.com/whitexiong/laravel-angular-blog "laravel 8 + angular + markdown ") 會持續的進行開源