異常捕捉
異常捕捉(看云文檔)內容挺多的,自己去百度吧,我就把我遇到過的常見的錯誤進行捕捉,其它的異常我也愛莫能助,不懂啊 !>_>!
我也就不自定義類了,直接在它給的默認的異常處理文件里寫了。

(1)參數驗證錯誤捕捉
我們先寫一個參數驗證的類,在app目錄下創建validate目錄,創建User.php文件
app/validate/User.php
```
<?php
namespace app\validate;
use think\Validate;
class User extends Validate
{
protected $rule = [
'name' => 'require|max:25',
'age' => 'number|between:1,120',
'email' => 'email',
];
protected $message = [
'name.require' => '名稱必須',
'name.max' => '名稱最多不能超過25個字符',
'age.number' => '年齡必須是數字',
'age.between' => '年齡只能在1-120之間',
'email' => '郵箱格式錯誤',
];
}
```
tp6的異常捕捉分為兩種,自動和手動的,手動的就是通過try{}catch{}捕捉。tp6的異常捕捉大多是自動的,不過,比如我們現在要操作的參數驗證錯誤就需要自己去捕捉來拋出異常,我們此節的目的是統一捕捉這個錯誤,我就不用手動的了。
我們就在異常處理類的render方法中添加這個捕捉拋出就可以了。

```
// 1.參數驗證錯誤
if ($e instanceof ValidateException) {
return result($e->getError(), '參數驗證不通過', 422);
}
```
現在在方法中一下,看看能否捕獲。
app/controller/v1/User.php

查看結果,成功被捕獲到了,并拋出了錯誤內容

如果驗證通過了,就會正常的走下去,則會顯示我return的測試內容

(2)未匹配到資源或方法的異常捕獲
我還沒找到方法,在我的預想中這個應該要做到能夠準確的反應未匹配到的原因。
```
// 2.方法(控制器、路由、http請求)、資源(多媒體文件,如視頻、文件)未匹配到,
// 一旦在定義的路由規則中匹配不到,它就會直接去匹配控制器,但是因為在控制器中做了版本控制v1,v2這樣的,所以它是無法獲取對應控制器的
// 所以都會直接走了HttpException的錯誤
// 感覺好像也無所謂,反正是做api接口的,只不過這樣就不好準確的提示信息了
// 到底這個請求時控制器找不到呢?還是方法找不到?還是請求類型(get,post)不對?
if(($e instanceof ClassNotFoundException || $e instanceof RouteNotFoundException) || ($e instanceof HttpException && $e->getStatusCode()==404)){
$data = [
'err_msg' => $e -> getMessage(),
'tips_1' => '請檢查路徑是否是否填寫正確',
'tips_2' => '請檢查請求類型是否正確',
];
return result($data, '方法或資源未找到,請檢查', 404);
}
```
#### 下面就不寫了,太麻煩了,直接放全部代碼
```
<?php
namespace app;
use ParseError; // 語法錯誤
use TypeError;
use InvalidArgumentException; // 參數錯誤
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\db\exception\PDOException; // 數據庫連接錯誤
use think\db\exception\DbException; // 數據庫模型訪問錯誤,比如方法不存在
use think\exception\RouteNotFoundException;
use think\exception\ClassNotFoundException;
use think\exception\FuncNotFoundException;
use think\exception\FileException;
use think\exception\Handle;
use think\exception\HttpException;
use think\exception\HttpResponseException;
use think\exception\ValidateException;
use think\exception\ErrorException;
use think\Response;
use Throwable;
/**
* 應用異常處理類
*/
class ExceptionHandle extends Handle
{
/**
* 不需要記錄信息(日志)的異常類列表
* @var array
*/
protected $ignoreReport = [
HttpException::class,
HttpResponseException::class,
ModelNotFoundException::class,
DataNotFoundException::class,
ValidateException::class,
];
/**
* 記錄異常信息(包括日志或者其它方式記錄)
*
* @access public
* @param Throwable $exception
* @return void
*/
public function report(Throwable $exception): void
{
// 使用內置的方式記錄異常日志
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
*
* @access public
* @param \think\Request $request
* @param Throwable $e
* @return Response
*/
public function render($request, Throwable $e): Response
{
// 添加自定義異常處理機制
// 請求異常
if ($e instanceof HttpException && $request->isAjax()) {
return response($e->getMessage(), $e->getStatusCode());
}
// 使用了錯誤的數據類型 或 缺失參數
if ($e instanceof InvalidArgumentException || $e instanceof ErrorException) {
$fileUrlArr = explode(DIRECTORY_SEPARATOR, $e->getFile());
$data = [
'err_msg' => $e->getMessage(),
'file' => $fileUrlArr[count($fileUrlArr) - 1],
'line' => $e->getLine()
];
return result($data, '參數錯誤', 413);
}
// 1.參數驗證錯誤
if ($e instanceof ValidateException) {
return result($e->getError(), '參數驗證不通過', 422);
}
// 2.方法(控制器、路由、http請求)、資源(多媒體文件,如視頻、文件)未匹配到,
// 一旦在定義的路由規則中匹配不到,它就會直接去匹配控制器,但是因為在控制器中做了版本控制v1,v2這樣的,所以它是無法獲取對應控制器的
// 所以都會直接走了HttpException的錯誤
// 感覺好像也無所謂,反正是做api接口的,只不過這樣就不好準確的提示信息了
// 到底這個請求時控制器找不到呢?還是方法找不到?還是請求類型(get,post)不對?
if(($e instanceof ClassNotFoundException || $e instanceof RouteNotFoundException) || ($e instanceof HttpException && $e->getStatusCode()==404)){
$data = [
'err_msg' => $e -> getMessage(),
'tip_1' => '請檢查路徑是否是否填寫正確',
'tips_2' => '請檢查請求類型是否正確',
];
return result($data, '方法或資源未找到,請檢查', 404);
}
// 3.語法錯誤
if ($e instanceof ParseError) {
$fileUrlArr = explode(DIRECTORY_SEPARATOR, $e->getFile());
$data = [
'err_msg' => $e->getMessage(),
'file' => $fileUrlArr[count($fileUrlArr) - 1],
'line' => $e->getLine()
];
return result($data, '服務器異常-語法錯誤', 411);
}
// 4.數據庫錯誤
if ($e instanceof PDOException || $e instanceof DbException) {
$fileUrlArr = explode(DIRECTORY_SEPARATOR, $e->getFile());
$data = [
'err_msg' => $e->getMessage(),
'file' => $fileUrlArr[count($fileUrlArr) - 1],
'line' => $e->getLine()
];
return result($data, '服務器異常-數據庫錯誤', 412);
}
// 其他錯誤交給系統處理
return parent::render($request, $e);
}
}
```
- 空白目錄
- 使用thinkphp6搭建后端api接口流程
- tp6 uniapp vue 前后端跨域解決方案
- 操作記錄
- api00
- 你看看有沒有用
- 6666
- Docker安裝LNMP環境的詳細過程(可部署TP項目)
- LNMP部署thinkphp
- 玩客云Armbian 安裝LNMP環境 Docker
- ThinkPHP6項目基操(16.實戰部分 redis+token登錄)
- ThinkPHP6項目基操(11.實戰部分 部署后臺靜態頁面模板及后臺登錄頁面)
- ThinkPHP6項目基操(13.實戰部分 項目中的自定義異常處理總結 錯誤頁面API錯誤)
- ThinkPHP6項目基操(14.實戰部分 中間件處理登錄流程)
- ThinkPHP6項目基操(12.實戰部分 驗證碼)
- ThinkPHP6項目基操(18.實戰部分 表單令牌Token 防CSRF)
- ThinkPHP6項目基操(19.實戰部分 Mysql模型事務操作)
- ThinkPHP6項目基操(20.實戰部分 數據庫操作返回值總結)
- 瀏覽器端判斷當前設備的運行環境
- api
- api異常捕捉
- 寫一個中間件
- 統一的參數返回形式
- ThinkPHP6調用模型的方法
- thinkphp6控制器、驗證器、模型、service,各層寫的內容