ThinkPHP8 应用异常处理类,让接口更优雅

普通处理接口有时报错返回的信息,显得不专业且体验极差,特别是对使用的用户而言。今天整理下ThinkPHP8(ThinkPHP6也适用)应用异常处理文档。

(附上一张未处理的应用异常图)

一、在PHP中,可以使用异常处理来处理代码中出现的错误或者不可预见的情况

  • 提高程序稳定性:通过捕获和处理异常,可以确保应用程序在遇到问题时不会崩溃,而是能够继续执行。
  • 错误报告:异常处理允许记录和报告错误信息,便于开发人员了解和解决问题。
  • 用户友好:适当的异常处理可以提供更友好的用户界面,避免向用户显示晦涩的错误消息。
  • 资源管理:异常处理还可以用于释放资源,如文件、数据库连接和网络连接,确保它们在不再需要时被正确关闭。

二、异常处理类

在项目的应用目录下(app)存在着一个 ExceptionHandle.php 文件 可以在这里对应用的异常进行处理。

<?php
namespace app;

use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\exception\Handle;
use think\exception\HttpException;
use think\exception\HttpResponseException;
use think\exception\InvalidArgumentException;
use think\exception\ValidateException;
use think\Response;
use Throwable;
use ParseError; // 语法错误
use think\db\exception\PDOException; // 数据库连接错误
use think\db\exception\DbException; // 数据库模型访问错误,比如方法不存在
use think\exception\RouteNotFoundException;
use think\exception\ClassNotFoundException;


/**
 * 应用异常处理类
 */
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 self::result($e->getMessage(), $e->getStatusCode());
        }
        // ②错误的数据类型 或 缺失参数 413
        if ($e instanceof InvalidArgumentException ) {
            $fileUrlArr = explode(DIRECTORY_SEPARATOR, $e->getFile());
            $data = [
                'err_msg' => $e->getMessage(),
                'file' => $fileUrlArr[count($fileUrlArr) - 1],
                'line' => $e->getLine()
            ];
            return self::result('参数错误',$data,413);
        }
        // ③参数验证错误 422
        if ($e instanceof ValidateException) {
            return self::result('参数验证不通过',$e->getError(), 422);
        }
        // 2.方法、资源未匹配到 404
        if(($e instanceof ClassNotFoundException || $e instanceof RouteNotFoundException) || ($e instanceof HttpException && $e->getStatusCode()==404)){
            $data = [
                'err_msg' => $e -> getMessage(),
            ];
            return self::result('方法或资源未找到,请检查',$data, 404);
        }
        // ④语法错误
        if ($e instanceof ParseError) {
            $fileUrlArr = explode(DIRECTORY_SEPARATOR, $e->getFile());
            $data = [
                'err_msg' => $e->getMessage(),
                'file' => $fileUrlArr[count($fileUrlArr) - 1],
                'line' => $e->getLine()
            ];
            return self::result('服务器异常-语法错误',$data,411);
        }
        // ⑤数据库错误
        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 self::result('服务器异常-数据库错误',$data,412);
        }

        // apidoc的异常未被正确响应
        if ($e instanceof \hg\apidoc\exception\HttpException) {
            $data = [
                'err_msg' => $e->getMessage(),
                'line' => $e->getLine()
            ];
            return self::result('参数错误',$data, $e->getCode());
        }
        // 其他错误交给系统处理
        return parent::render($request, $e);
    }

    /**
     * 统一返回处理
    */
   public function result(string $msg = 'error', array $data = [], int $code = 200, string $type = 'json'): Response
    {
        $result = [
            "code" => $code,
            "msg" => $msg,
            "data" => $data
        ];
        // 调用Response的create方法,指定code可以改变请求的返回状态码
        return Response::create($result, $type)->code($code);
    }
}

应用异常捕捉后处理结果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值