ThinkPHP6项目基操(13.实战部分 项目中的自定义异常处理总结 错误页面&API错误)_thinkphp6自定义403和404页面-程序员宅基地

技术标签: 异常处理  错误处理  thinkphp6  thinkphp  tp6  Thinkphp  

前言

  一般项目中路由分为返回模板引擎页面和返回api接口json数据,两种方式异常需要返回不同的内容,如果是模板引擎页面遇到异常需要返回错误页面,如果是api接口遇到异常需要返回json数据。
  开发模式和上线模式应该返回不同的内容,开发模式应该尽可能返回具体的错误信息,上线模式则不能返回具体的错误信息,一般显示“服务器错误,请稍后重试”类似友好的提示,而不是显示一堆报错代码(既不友好又不安全)。
  如果有更好的方法,欢迎提出意见。

一、异常分类

1. 控制器找不到

在访问路由时,若控制器不对,需要使用空控制器拦截报错。

2. 方法找不到

方法找不到可以修改app目录下的BaseController控制器重写__call方法。

3. 请求资源不存在

自定义拦截报错信息,可以使用Provider自定义错误处理类,重写render方法,根据不同的错误返回不同的数据。

4. 系统內部异常、HTTP异常等

同第3点。

二、异常处理

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,error)显示:

<p class="error-message">{$e ?? ''}</p>

三、异常检测

异常检测分浏览器页面访问异常api接口返回异常,还需要检查开发模式线上模式

  1. 控制器不存在
  2. 方法不存在
  3. 主动抛出异常
  4. 系统抛出异常

Tips: api接口可以使用Postman工具模拟,添加Headers
Content-Typeapplication/x-www-form-urlencoded
X-Requested-Withxmlhttprequest

(博主比较懒就不贴截图了,但是都测试过,同志们自己试一下,算了还是贴一张吧)
在这里插入图片描述


️重磅推荐:免费商用电商系统

想白嫖整个电商系统用来商用?
想有自己的商城实现财富自由?
想学习最佳实践提升自己技术?

快来进入 传送门 ,开源免费、完整示例带你快速入门,轻松二开,走上人生巅峰!
在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zy1281539626/article/details/110847728

智能推荐

unity3d 实现简单水墨画效果_unity3d shader 水墨动画-程序员宅基地

文章浏览阅读6.6k次,点赞2次,收藏8次。水墨效果,素材简陋:文章参考http://gad.qq.com/article/detail/18724,原理可以看这位大佬的文章,我就贴上自己工程源码:https://download.csdn.net/my_unity3d shader 水墨动画

(Java毕业设计)招聘信息管理系统(基于java+springboot)附源码_java人力资源管理系统招聘管理-程序员宅基地

文章浏览阅读1.1k次,点赞2次,收藏17次。在Internet高速发展的今天,我们生活的各个领域都涉及到计算机的应用,其中包括招聘信息管理系统的网络应用,在外国招聘信息管理系统已经是很普遍的方式,不过国内的线上管理系统可能还处于起步阶段。招聘信息管理系统具有招聘信息管理功能的选择。_java人力资源管理系统招聘管理

冯诺依曼、哈佛、RISC、CISC_冯诺依曼曼指令和数据区分-程序员宅基地

文章浏览阅读1.3w次,点赞5次,收藏20次。几个基础材料(源:http://jwc.seu.edu.cn/zq/signal/new/importent/zhang5_6/feng.htmhttp://jwc.seu.edu.cn/zq/signal/new/importent/zhang5_6/harvard.htmhttp://dingjun.net/dingjun/html/14/84FB43402106C575.html_冯诺依曼曼指令和数据区分

Netty——深入解析心跳检测机制_netty 服务端心跳检测-程序员宅基地

文章浏览阅读428次。客户端定时每X秒(推荐小于60秒)向服务端发送特定数据(任意数据都可),服务端设定为X秒没有收到客户端心跳则认为客户端掉线,并关闭连接触发onClose回调。当需要服务端定时给客户端发送心跳数据时, $gateway->pingData设置为服务端要发送的心跳请求数据,心跳数据是任意的,只要客户端能识别即可。当设置为服务端主动发送心跳时,如果客户端最近有发来数据,那么证明客户端存活,服务端会省略一个心跳,下个心跳大约1.5*$gateway->pingInterval秒后发送。心跳检测时间间隔 单位:秒。_netty 服务端心跳检测

linux内核SPI总线驱动分析(一)_linux spi驱动总线分析-程序员宅基地

文章浏览阅读535次。下面有两个大的模块:一个是SPI总线驱动的分析 (研究了具体实现的过程)另一个是SPI总线驱动的编写(不用研究具体的实现过程)SPI总线驱动分析 1 SPI概述 SPI是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口,是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主要应_linux spi驱动总线分析

Nginx,nginx-rtmp-module-master搭建直播平台-程序员宅基地

文章浏览阅读511次。Nginx,nginx-rtmp-module-master搭建直播平台_nginx-rtmp-module-master

随便推点

springboot2.x The character [_] is never valid in a domain name_springboot the character [_] is never valid in a d-程序员宅基地

文章浏览阅读1k次。访问springcloud工程, springboot版本为2.1.15 ,使用域名访问接口报400但是直接用ip不报错。发现是集成的tomcat版本不支持域名下划线。大约是8.5.31以后的版本不支持带下划线的域名,但是也没办法降低版本了,会有很多冲突。先搁置。..._springboot the character [_] is never valid in a domain name.

QEMU 运行 RISC-V 64 位 Linux_qemu启动riscv环境-程序员宅基地

文章浏览阅读420次。QEMU 运行 RISC-V 64 位 Linux_qemu启动riscv环境

一年对于程序员来说有多长?_程序员 一年多少秒-程序员宅基地

文章浏览阅读4.3k次。聊这个话题,我表示又蛋疼了!你想看么?还没写过这么有争议的话题,有点小小的不安!一年有多长?让我来掐指算一算:1年=365天(今年是366天)=多少小时呢?前方高能,等我去写个程序算一下!还用写程序吗?早有人写好了!有多少分有多少秒,又有多少毫秒呢?我们只需要选择一下单位就好了,结果是:1年(yr)=31536000000毫秒(ms)为什么聊这个话题?蛋当然不可能说疼就疼了!水是有源的,树是有根的_程序员 一年多少秒

idea使用码云管理项目教程_idea 使用码云维护项目-程序员宅基地

文章浏览阅读745次。第一步 : 下载git 进入git官网 https://git-scm.com/download/win 下载git软件. 我这里演示安装Git-2.16.1.4-64-bit.exe 1 . 运行 Git-2.16.1.4-64-bit.exe 点击Next 2. 选择安装目录 点击Next 3. 第二步 : 安装码云插件第三步 : 配..._idea 使用码云维护项目

js调用百度地图API创建地图,搜索位置-程序员宅基地

文章浏览阅读186次。实现代码:&lt;!DOCTYPE html&gt;&lt;html&gt;&lt;head&gt; &lt;meta charset="UTF-8"&gt; &lt;meta http-equiv="Cache-Control" content="no-store" /&gt; &lt;meta http-equi_百度地图js api地址搜索

Excel VSTO开发1-VSTO简介_office开发版本号与vsto-程序员宅基地

文章浏览阅读986次。VSTO(Visual Studio Tools for Office)是微软开发的一种用于创建Microsoft Office应用程序的工具集,它可以让开发者在Microsoft Office应用程序中集成自己的.NET应用程序。VSTO还提供了一些特殊的工具和库,使得开发人员可以更方便地管理Microsoft Office应用程序的生命周期、访问Microsoft Office应用程序的API和对象模型、处理Microsoft Office应用程序的事件和异常等。Office版本:2016 32位。_office开发版本号与vsto

推荐文章

热门文章

相关标签