ThinkPHP6プロジェクトの基本操作(13.一部の実際の戦闘プロジェクトでのカスタム例外処理の要約エラーページと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接口返回异常あり、チェックする必要が开发模式あり线上模式ます。

  1. コントローラが存在しません
  2. メソッドが存在しません
  3. 積極的に例外をスローする
  4. システムは例外をスローします

ヒント:apiインターフェースを使用できPostman、追加、ツールシミュレーションをHeaders
Content-Typeとしてapplication/x-www-form-urlencoded
X-Requested-WithISxmlhttprequest

(ブロガーは怠惰でスクリーンショットを投稿しませんが、すべてをテストしました。仲間が自分で試してみます。結局、投稿しましょう)
ここに写真の説明を挿入

おすすめ

転載: blog.csdn.net/zy1281539626/article/details/110847728