项目中的自定义异常处理总结 错误页面&API错误

  • 前言
  • 一、异常分类
    • 1. 控制器找不到
    • 2. 方法找不到
    • 3. 请求资源不存在
    • 4. 系统內部异常、HTTP异常等
  • 二、异常处理
    • 1. 前置处理
    • 2. 异常处理详细代码
      • (1) 控制器找不到
      • (2) 方法找不到
      • (3) 请求资源不存在及系统错误异常
  • 三、异常检测

前言

  一般项目中路由分为返回模板引擎页面和返回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添加相应的状态码配置:

<?phpreturn ["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下全部应用。

<?phpnamespace 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

<?phpnamespace 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

(博主比较懒就不贴截图了,但是都测试过,同志们自己试一下,算了还是贴一张吧)


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

ThinkPHP6项目基操(13.实战部分 项目中的自定义异常处理总结 错误页面API错误)相关推荐

  1. ThinkPHP6项目基操(15.实战部分 阿里云短信redis)

    阿里云短信redis 一.安装阿里云短信SDK 二.封装到项目lib中 三.radis记录验证码 1. 安装redis服务 2. 可视化redis管理软件 3. PHP安装redis扩展 4. 配置缓 ...

  2. ThinkPHP6项目基操目录

    前言 ThinkPHP是一个免费开源的,快速.简单的面向对象的轻量级PHP开发框架,是为了敏捷WEB应用开发和简化企业应用开发而诞生的.ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色 ...

  3. ThinkPHP6项目基操(11.实战部分 部署后台静态页面模板及后台登录页面)

    实战部分 部署后台静态页面模板及后台登录页面 前言 一.部署静态资源到项目 1.新建后台静态资源文件夹 二.后台登录页面 1. 目录结构 2. 模板字符串替换配置 前言 网站后台一般是在基础静态页面上 ...

  4. ThinkPHP6项目基操(4.拦截无效请求 控制器或方法不存在)

    拦截无效请求 控制器或方法不存在 一.默认无效请求 二.显示具体错误信息 方法1.配置`config/app.php` 方法2. 配置`.env`环境变量 三.处理错误 1. 方法不存在 2. 控制器 ...

  5. php登陆项目,ThinkPHP6项目基操(14.实战部分 中间件处理登录流程)

    一.定义中间件 namespace app\middleware; class Check { public function handle($request, \Closure $next) { i ...

  6. ThinkPHP6项目基操(20.实战部分 数据库操作返回值总结)

    数据库操作返回值总结 0. 前言 1. Db类操作数据库 1.1 新增 1.2 更新 1.3 删除 1.3.1 单条删除 1.3.2 批量删除 1.4 查询 1.4.1 单笔记录 1.4.2 多笔记录 ...

  7. ThinkPHP6项目基操(19.实战部分 Mysql模型事务操作)

    模型事务操作 前言 1. Mysql数据库注意 2. thinkPHP模型使用事务 前言 事务操作在复杂的数据库操作的时候尤为重要,特别是在操作多张表的时候,如果某一步骤出错了,就会导致有脏数据,会很 ...

  8. ThinkPHP6项目基操(18.实战部分 表单令牌Token 防CSRF)

    表单令牌Token 0. 前言 1. TP6 令牌token使用 1.1 表单提交 1.2 AJAX提交 2. TP6 令牌token验证 2.1 路由验证 2.2 控制器验证 2.3 验证器验证 0 ...

  9. ThinkPHP6项目基操(17.实战部分 Filesystem文件上传)

    Filesystem文件上传 控制器: <?php namespace app\admin\controller; use app\BaseController; use think\facad ...

最新文章

  1. 02移动端布局基础之流式布局项目实战(京东移动端首页)
  2. 启用CentOS6.5 64位安装时自带的MySQL数据库服务器
  3. Android 编译环境的依赖库安装
  4. Django从理论到实战(part28)--ORM常用Field详解
  5. ora-01092: oracle 实例终止.强制断开连接,undo表空间故障特殊恢复(二)------ORA-01092: ORACLE 实例终止。强制断开连接...
  6. 斗鱼回应与虎牙合并;Android 11 Beta 3 发布| 极客头条
  7. 用curl访问HTTPS站点并登录
  8. MapReduce on Yarn 的流程和架构图
  9. R语言︱非结构化数据处理神器——rlist包
  10. 论文写作——算法部分写作心得
  11. 新MacBook Pro软件安装记录
  12. 戴尔笔记本电脑插入有线耳机后仍然外放的一种解决办法
  13. LeetCode1436 旅行终点站
  14. 参考线平滑-FemPosDeviation-SQP
  15. 无人驾驶学习(二):定位与导航
  16. 领淘宝优惠券的微信小程序
  17. 微信服务器与客户端消息通讯机制,微信在部分地区发生连接故障,你遇到了么?...
  18. Android studio连接(逍遥)模拟器
  19. paypal是怎么收费的?
  20. 什么是RC低通滤波电路

热门文章

  1. ajax核心技术1---XMLHttpRequset对象的使用
  2. 我会铭记这一天:2016年10月25日
  3. DB2常用函数:字符串函数
  4. 在安全模式下激活xp
  5. 【转】vc6.0移植到VS2010遇到的问题,散分给大家,虽然分不多,各位帮忙
  6. SSIS 错误代码 DTS_E_OLEDB_EXCEL_NOT_SUPPORTED 没有可用的 OLE DB 访问接口 SSIS 的 64 位版本中不支持 Excel 连接管理器...
  7. 但救地球要紧的飞鸽传书
  8. 免费软件做的不错的,这里要说一个叫《飞秋》的软件
  9. 便把他手中的i698源代码拐杖转了一圈
  10. 《飞秋下载》介绍过的求伯君,看看!