Skip to content

异常处理指南

本文档介绍 DSPlatform 项目中异常处理的使用方法,包括异常类型、使用场景和最佳实践。

概述

DSPlatform 使用自定义异常类来处理不同类型的业务错误,所有异常都继承自 \RuntimeException,并通过 ExceptionHandle 统一处理,返回统一的 JSON 响应格式。

异常类型

1. CommonException(通用业务异常)

使用场景:业务逻辑错误、参数错误、重复操作等

HTTP 状态码:200(业务错误)

示例

php
// 业务规则违反
if ($user_points < $need_points) {
    throw new CommonException('积分不足');
}

// 参数错误
if (empty($store_id)) {
    throw new CommonException('参数缺失或无效: store_id');
}

2. AuthException(认证异常)

使用场景:用户未登录、Token 无效、登录过期等

HTTP 状态码:401 或 403

示例

php
// 未登录
if (!$this->user_id) {
    throw new AuthException('请先登录');
}

// Token 过期
if ($token_expired) {
    throw new AuthException('Token 已过期,请重新登录', 401);
}

3. PermissionException(权限异常)

使用场景:用户已登录但权限不足,通过 getAvailableActions 检查

HTTP 状态码:403

示例

php
// 操作权限不足
if (!in_array('cancel', $user_available_actions)) {
    throw new PermissionException('用户没有取消订单权限');
}

// 资源权限不足
if (!in_array($store_id, $user_store_list)) {
    throw new PermissionException('您没有权限操作此店铺');
}

4. StateException(状态异常)

使用场景:状态机/工作流中状态不符合操作要求,直接检查状态

HTTP 状态码:200(业务错误)

示例

php
// 订单状态错误
if ($order_info['order_status'] !== TblOrderEnum::ORDER_STATUS_PENDING) {
    throw new StateException('订单状态不是未付款,不能修改订单金额');
}

// 退款状态不允许
if (!in_array($refund_status, [STATUS_PROCESSING, STATUS_FAILED])) {
    throw new StateException('当前退款状态不允许此操作');
}

5. SystemException(系统异常)

使用场景:系统层面错误,如分布式锁获取失败、乐观锁版本冲突、系统资源不可用等

HTTP 状态码:503 或 409

示例

php
// 分布式锁获取失败(系统繁忙)
if (!CacheUtil::acquireLock($lockKey, 5)) {
    throw new SystemException('余额更新失败,系统繁忙,请稍后重试');
}

// 乐观锁重试失败(并发冲突)
if ($retryCount >= $maxRetries) {
    throw new SystemException('余额更新失败,版本冲突,已重试' . $maxRetries . '次', 409);
}

6. PayException(支付异常)

使用场景:支付相关错误,如支付失败、支付渠道错误、支付金额错误等

HTTP 状态码:200(业务错误)

示例

php
// 支付失败
try {
    $result = $pay->pay($order);
} catch (\Exception $e) {
    throw new PayException('支付宝支付失败: ' . $e->getMessage());
}

// 支付渠道错误
if (!in_array($pay_type, ['alipay', 'wechat'])) {
    throw new PayException('支付渠道不存在');
}

7. NotFoundException(资源未找到异常)

使用场景:数据查询结果为空,如订单不存在、用户不存在等

HTTP 状态码:404

示例

php
if (!$order_info) {
    throw new NotFoundException('订单不存在');
}

异常分类对比

异常类型使用场景HTTP状态码典型示例
CommonException业务逻辑错误、参数错误200"积分不足"、"参数缺失"
AuthException认证失败(未登录)401/403"请先登录"、"Token 已过期"
PermissionException权限不足(已登录但无权限)403"用户没有取消订单权限"
StateException状态错误(直接检查状态)200"订单状态不是未付款"
SystemException系统层面错误503/409"系统繁忙"、"版本冲突"
PayException支付相关错误200"支付失败"、"支付渠道错误"
NotFoundException资源未找到404"订单不存在"、"用户不存在"

异常处理流程

1. 异常抛出

在 Service 层或 Controller 层抛出异常:

php
use app\deshang\exceptions\CommonException;
use app\deshang\exceptions\NotFoundException;

// Service 层
public function getUserInfo($user_id)
{
    $user_info = (new UserDao())->getUserInfoById($user_id);
    if (!$user_info) {
        throw new NotFoundException('用户不存在');
    }
    return $user_info;
}

2. 异常捕获

ExceptionHandle 自动捕获所有异常,并返回统一的 JSON 格式:

json
{
    "code": 10001,
    "msg": "用户不存在",
    "data": ""
}

3. 异常记录

所有异常都会自动记录到 sys_error_logs 表中,包括:

  • 异常类名(exception_class
  • 异常消息(message
  • 请求信息(controllerrootip等)
  • 错误堆栈(trace

最佳实践

1. 选择合适的异常类型

  • 业务逻辑错误CommonException
  • 未登录/认证失败AuthException
  • 已登录但权限不足PermissionException
  • 状态不符合要求StateException
  • 系统层面错误SystemException
  • 支付相关错误PayException
  • 资源不存在NotFoundException

2. 异常消息要清晰

php
// ✅ 好的示例
throw new CommonException('积分不足,当前积分:' . $user_points . ',需要积分:' . $need_points);

// ❌ 不好的示例
throw new CommonException('错误');

3. 避免过度使用 CommonException

php
// ❌ 不推荐:所有错误都用 CommonException
throw new CommonException('订单状态错误');
throw new CommonException('用户没有权限');

// ✅ 推荐:使用专门的异常类型
throw new StateException('订单状态错误');
throw new PermissionException('用户没有权限');

4. 权限检查的两种方式

方式一:通过 getAvailableActions 检查(推荐)

php
$user_available_actions = $this->getUserOrderActions($order_info);
if (!in_array('cancel', $user_available_actions)) {
    throw new PermissionException('用户没有取消订单权限');
}

方式二:直接检查状态

php
if ($order_info['order_status'] !== TblOrderEnum::ORDER_STATUS_PENDING) {
    throw new StateException('订单状态不是未付款,不能取消订单');
}

5. 系统异常的使用场景

SystemException 主要用于:

  • 分布式锁获取失败(系统繁忙)
  • 乐观锁版本冲突(并发冲突)
  • 系统资源不可用(缓存、队列等)

这些异常通常需要重试机制,不应直接暴露给用户。

异常类位置

所有异常类位于 app/deshang/exceptions/ 目录:

app/deshang/exceptions/
├── CommonException.php      # 通用业务异常
├── AuthException.php         # 认证异常
├── PermissionException.php  # 权限异常
├── StateException.php        # 状态异常
├── SystemException.php       # 系统异常
├── PayException.php          # 支付异常
└── NotFoundException.php     # 资源未找到异常

相关文档


最后更新:2024-01-20
维护者:DSPlatform技术团队(德尚网络)

获取帮助

如果您在使用过程中遇到问题,可以通过以下方式获取帮助:

  • 官方网站https://www.csdeshang.com
  • 电话咨询:15364080101(微信同号)
  • QQ咨询:858761000
  • 邮箱咨询:858761000@qq.com
  • 工作时间:工作日 9:00-18:00
  • 微信咨询:扫码添加微信
微信二维码

版权所有 © 2014-至今 德尚网络