プロジェクトエラーページとAPIエラーでのカスタム例外処理の概要
序文
通常、プロジェクトのルーティングはリターン模板引擎页面
とリターンに分けられapi接口json数据
ます。2つの方法では、例外が発生した場合に異なるコンテンツを返す必要があります。テンプレートエンジンページで例外が発生した場合は、エラーページを返す必要があります。apiインターフェイスで例外が発生した場合は、jsonデータを返す必要があります。
開発モードとオンラインモードは異なるコンテンツを返す必要があります。開発モードはできるだけ多くの特定のエラー情報を返す必要がありますが、オンラインモードは特定のエラーメッセージを返すことはできません。通常、「サーバーエラー、後でもう一度やり直してください」などのわかりやすいプロンプトが表示されます。一連のエラーコードを表示する代わりに(非友好的および安全でない両方)。
より良い方法があれば、コメントを歓迎します。
1.異常分類
1.コントローラーが見つかりません
ルートにアクセスするときに、コントローラーが間違っている場合は、空控制器
インターセプトを使用してエラーを報告する必要があります。
2.メソッドが見つかりません
__callメソッドをオーバーライドするようにappディレクトリのBaseControllerコントローラーを変更するメソッドが見つかりません。
3.要求されたリソースが存在しません
エラーメッセージのインターセプトをカスタマイズするには、プロバイダーを使用してエラー処理クラスをカスタマイズし、renderメソッドをオーバーライドして、さまざまなエラーに応じてさまざまなデータを返すことができます。
4.システム内部例外、HTTP例外など。
同第3点。
2、例外処理
1.前処理
(1)
.env
ファイル定義APP_DEBUG
は、開発モードとオンラインモードを区別します。trueは開発モードを意味し、falseはオンラインモードを意味します。
APP_DEBUG = true
(2)返されるデータ形式を
app/common.php
ファイルで定義しますapi
。
function show($status, $message = 'error', $data = [], $httpStatus = 200){
$result = [
"status" => $status,
"message" => $message,
"result" => $data
];
return json($result, $httpStatus);
}
(3)現在のアプリケーションの下に新しいprovider.phpを作成し、カスタム例外処理クラスを指定します。
<?php
// 容器Provider定义文件
return [
'think\exception\Handle' => 'app\\admin\\exception\\Http',
];
(4)ステータスコード構成を定義するには、対応するステータスコード構成
config
をフォルダーの下にstatus.php
追加します。
<?php
return [
"success" => 1,
"error" => 0,
"http_status" => [
"not_found" => 404,
"validate_error" => 422,
"internal_error" => 500
]
];
(5)エラーページ(404、500など)を準備します。
2.詳細コードの処理の例外
(1)コントローラーが見つかりません
app/controller
ディレクトリError
(文件名固定为Error
)に新しいクラスを作成します。
这里需要注意的是,多应用的控制器应该定义在应用文件夹里,这里定义在app目录是为了作用于app下全部应用。
<?php
namespace app\controller;
class Error
{
public function __call($name, $arguments)
{
if(request()->isAjax()){
return show(config("status.error"), env('app_debug') ? "控制器{
$name}找不到" : '当前请求资源不存在,请稍后再试', [], config("status.http_status.not_found"));
}else{
return view(root_path() . 'public/error/admin/404.html', ['e' => env('app_debug') ? "控制器{
$name}找不到" : '当前请求资源不存在,请稍后再试'], config("status.http_status.not_found"));
}
}
}
(2)メソッドが見つかりません
app/BaseController.php
コントローラ追加__call
方法。
public function __call($name, $arguments)
{
if(request()->isAjax()){
return show(config("status.error"), env('app_debug') ? "找不到{
$name}方法" : '当前请求资源不存在,请稍后再试', [], config("status.http_status.not_found"));
}else{
return view(root_path() . 'public/error/admin/404.html', ['e' => env('app_debug') ? "{
$name}方法找不到" : '当前请求资源不存在,请稍后再试'], config("status.http_status.not_found"));
}
}
(3)要求されたリソースが存在せず、システムエラーが異常である
app\\admin\\exception\\Http
:
<?php
namespace app\admin\exception;
use ErrorException;
use Exception;
use InvalidArgumentException;
use ParseError;
use PDOException;
use think\exception\ClassNotFoundException;
use think\exception\Handle;
use think\exception\HttpException;
use think\exception\RouteNotFoundException;
use think\Response;
use Throwable;
use TypeError;
class Http extends Handle
{
/**
* 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
{
$returnCode = config("status.error");
$returnMessage = "系统异常,请稍后再试";
$returnData = [];
$httpStatus = 500;
if($e instanceof BusinessException){
// 自定义添加的业务异常
$returnMessage = $e->getMessage();
$httpStatus = config("status.http_status.business_error");
}else if($e instanceof ValidateException){
$returnMessage = $e->getError();
$httpStatus = config("status.http_status.validate_error");
}else if (($e instanceof ClassNotFoundException || $e instanceof RouteNotFoundException) || ($e instanceof HttpException && $e->getStatusCode() == 404)) {
$returnMessage = env('app_debug') ? $e->getMessage() : '当前请求资源不存在,请稍后再试';
$httpStatus = config("status.http_status.not_found");
}else if ($e instanceof Exception || $e instanceof PDOException || $e instanceof InvalidArgumentException || $e instanceof ErrorException || $e instanceof ParseError || $e instanceof TypeError || ($e instanceof HttpException && $e->getStatusCode() == 500)) {
$returnMessage = env('app_debug') ? $e->getMessage() : '系统异常,请稍后再试';
$httpStatus = config("status.http_status.internal_error");
}
if(request()->isAjax()){
return show($returnCode, $returnMessage, $returnData, $httpStatus);
}else{
if($httpStatus == config("status.http_status.not_found")){
$errorUrl = 'public/error/admin/404.html';
}else{
$errorUrl = 'public/error/admin/error.html';
}
return view(root_path() . $errorUrl, ['e'=>$returnMessage], $httpStatus);
}
}
}
上記のコードで返されたエラーメッセージはe
、エラーページ(404、エラー)に表示する必要があります。
<p class="error-message">{$e ?? ''}</p>
3、異常検出
異常検出ポイントブラウザ页面访问异常
でapi接口返回异常
あり、チェックする必要が开发模式
あり线上模式
ます。
- コントローラが存在しません
- メソッドが存在しません
- 積極的に例外をスローする
- システムは例外をスローします
ヒント:
api
インターフェースを使用できPostman
、追加、ツールシミュレーションをHeaders
:
Content-Type
としてapplication/x-www-form-urlencoded
X-Requested-With
ISxmlhttprequest
(ブロガーは怠惰でスクリーンショットを投稿しませんが、すべてをテストしました。仲間が自分で試してみます。結局、投稿しましょう)