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);
    }
}

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

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
thinkphp6中,异常处理是通过异常类来实现的。当系统出现异常时,会抛出一个异常对象,我们可以通过捕获这个异常对象来进行异常处理。以下是一个简单的异常处理示例: 1. 在控制器中抛出一个异常: ```php throw new \think\Exception('这是一个异常'); ``` 2. 在应用异常处理类中进行异常处理: ```php namespace app\exception; use think\exception\Handle; use think\Response; use Throwable; class Http extends Handle { public function render($request, Throwable $e): Response { // 根据不同异常类型进行处理 if ($e instanceof \think\Exception) { // 返回错误信息 return json(['msg' => $e->getMessage()], 500); } // 其他异常交给系统处理 return parent::render($request, $e); } } ``` 注意,上面的代码中,我们继承了think\exception\Handle类,并重写了它的render方法。render方法接受两个参数:$request表示当前请求对象,$e表示抛出的异常对象。在这个方法中,我们可以根据不同的异常类型进行处理,并返回一个Response对象。如果我们不需要对异常进行特殊处理,可以直接调用父类的render方法,让系统进行默认的异常处理。 3. 在应用的配置文件中配置异常处理类: ```php return [ // 异常处理类 'exception_handle' => 'app\exception\Http', ]; ``` 在上面的配置中,我们将异常处理类设置为app\exception\Http。这样,在应用出现异常时,系统就会自动调用这个类的render方法进行异常处理。 除了上面的方法,thinkphp6还提供了其他的异常处理方式,比如使用自定义的异常类、使用异常监听器等。你可以根据自己的需求选择合适的方式进行异常处理

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值