|
|
@@ -0,0 +1,245 @@
|
|
|
+# 修复Mex模块取消挂单Handler异常处理逻辑
|
|
|
+
|
|
|
+## 任务信息
|
|
|
+- **时间**: 2025年07月09日 16:19-16:40
|
|
|
+- **类型**: Bug修复 + 功能增强
|
|
|
+- **模块**: Mex(农贸市场)
|
|
|
+- **状态**: ✅ 已完成
|
|
|
+
|
|
|
+## 问题描述
|
|
|
+用户报告请求ID `69378280` 的取消挂单操作返回了 `SERVER_ERROR` 错误码和"系统繁忙,请稍后重试"的通用错误信息,但实际上这是一个业务逻辑错误(订单不存在),应该返回更具体的错误信息。
|
|
|
+
|
|
|
+## 问题分析
|
|
|
+
|
|
|
+### 1. 错误重现
|
|
|
+通过 `php artisan debug:reproduce-error 69378280` 重现了错误:
|
|
|
+- 请求:取消订单ID为2的挂单
|
|
|
+- 用户ID:39174
|
|
|
+- 实际问题:订单ID为2的订单不存在
|
|
|
+
|
|
|
+### 2. 代码问题
|
|
|
+在 `app/Module/AppGame/Handler/Matchexchange/CancelHandler.php` 中发现两个关键问题:
|
|
|
+
|
|
|
+#### 问题1:异常处理逻辑错误
|
|
|
+```php
|
|
|
+// 原始代码
|
|
|
+if (!$result['success']) {
|
|
|
+ throw new LogicException($result['message'] ?? '取消订单失败'); // 抛出LogicException
|
|
|
+}
|
|
|
+
|
|
|
+catch (\Exception $e) { // 但被这里捕获了
|
|
|
+ // 系统异常处理
|
|
|
+ $this->response->setCode(RESPONSE_CODE::SERVER_ERROR);
|
|
|
+ $this->response->setMsg('系统繁忙,请稍后重试');
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+#### 问题2:响应对象设置错误
|
|
|
+```php
|
|
|
+// 错误的响应设置
|
|
|
+$this->response->setCode(RESPONSE_CODE::SERVER_ERROR); // 设置了$this->response
|
|
|
+return $response; // 但返回的是局部$response对象
|
|
|
+```
|
|
|
+
|
|
|
+## 解决方案
|
|
|
+
|
|
|
+### 1. 修复异常处理逻辑
|
|
|
+- 区分 `LogicException`(业务逻辑异常)和系统异常
|
|
|
+- 业务逻辑异常返回 `VALIDATE_ERROR`
|
|
|
+- 系统异常返回 `SERVER_ERROR`
|
|
|
+
|
|
|
+### 2. 修复响应对象设置
|
|
|
+- 统一使用 `$this->response` 设置响应码和消息
|
|
|
+- 确保响应设置和返回对象一致
|
|
|
+
|
|
|
+### 3. 优化错误处理流程
|
|
|
+- 参数验证失败:直接返回 `VALIDATE_ERROR`
|
|
|
+- 业务逻辑失败:返回 `VALIDATE_ERROR` 和具体错误信息
|
|
|
+- 系统异常:返回 `SERVER_ERROR` 和通用错误信息
|
|
|
+
|
|
|
+## 核心代码修改
|
|
|
+
|
|
|
+### 修改前
|
|
|
+```php
|
|
|
+try {
|
|
|
+ // 业务逻辑
|
|
|
+ if (!$result['success']) {
|
|
|
+ throw new LogicException($result['message'] ?? '取消订单失败');
|
|
|
+ }
|
|
|
+} catch (\Exception $e) {
|
|
|
+ // 所有异常都被当作系统异常处理
|
|
|
+ $this->response->setCode(RESPONSE_CODE::SERVER_ERROR);
|
|
|
+ $this->response->setMsg('系统繁忙,请稍后重试');
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 修改后
|
|
|
+```php
|
|
|
+try {
|
|
|
+ // 参数验证
|
|
|
+ if (!$orderId || $orderId <= 0) {
|
|
|
+ $this->response->setCode(RESPONSE_CODE::VALIDATE_ERROR);
|
|
|
+ $this->response->setMsg("订单ID无效");
|
|
|
+ return $response;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 业务逻辑
|
|
|
+ if (!$result['success']) {
|
|
|
+ $this->response->setCode(RESPONSE_CODE::VALIDATE_ERROR);
|
|
|
+ $this->response->setMsg($result['message'] ?? '取消订单失败');
|
|
|
+ return $response;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 成功响应
|
|
|
+ $this->response->setCode(RESPONSE_CODE::OK);
|
|
|
+ $this->response->setMsg('订单取消成功');
|
|
|
+
|
|
|
+} catch (LogicException $e) {
|
|
|
+ // 业务逻辑异常
|
|
|
+ $this->response->setCode(RESPONSE_CODE::VALIDATE_ERROR);
|
|
|
+ $this->response->setMsg($e->getMessage());
|
|
|
+
|
|
|
+} catch (\Exception $e) {
|
|
|
+ // 系统异常
|
|
|
+ $this->response->setCode(RESPONSE_CODE::SERVER_ERROR);
|
|
|
+ $this->response->setMsg('系统繁忙,请稍后重试');
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+## 测试验证
|
|
|
+
|
|
|
+### 1. 错误情况测试
|
|
|
+```bash
|
|
|
+curl -X POST http://kku_laravel.local.gd/gameapi \
|
|
|
+ -H "Content-Type: application/json" \
|
|
|
+ -H "token: b8c887eae90d1e95b2c91304617f13d2" \
|
|
|
+ -d '{"matchexchangeCancel":{"id":"2"}}'
|
|
|
+```
|
|
|
+
|
|
|
+**修复前响应**:
|
|
|
+```json
|
|
|
+{
|
|
|
+ "code": "SERVER_ERROR",
|
|
|
+ "msg": "系统繁忙,请稍后重试"
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**修复后响应**:
|
|
|
+```json
|
|
|
+{
|
|
|
+ "code": "VALIDATE_ERROR",
|
|
|
+ "msg": "订单不存在"
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 2. 正常情况测试
|
|
|
+```bash
|
|
|
+curl -X POST http://kku_laravel.local.gd/gameapi \
|
|
|
+ -H "Content-Type: application/json" \
|
|
|
+ -H "token: b8c887eae90d1e95b2c91304617f13d2" \
|
|
|
+ -d '{"matchexchangeCancel":{"id":"6542"}}'
|
|
|
+```
|
|
|
+
|
|
|
+**响应**:
|
|
|
+```json
|
|
|
+{
|
|
|
+ "code": "OK",
|
|
|
+ "msg": "订单取消成功",
|
|
|
+ "deduct": {"coins": [{"type": 3, "quantity": 675}]},
|
|
|
+ "reward": {"coins": [{"type": 2, "quantity": 675}]}
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+## 修复效果
|
|
|
+
|
|
|
+### ✅ 问题解决
|
|
|
+1. **错误码准确性**:业务逻辑错误返回 `VALIDATE_ERROR` 而非 `SERVER_ERROR`
|
|
|
+2. **错误信息具体性**:返回具体错误信息(如"订单不存在")而非通用信息
|
|
|
+3. **异常处理规范性**:区分业务异常和系统异常,分别处理
|
|
|
+4. **响应对象一致性**:修复响应设置和返回对象不一致的问题
|
|
|
+
|
|
|
+### ✅ 用户体验改善
|
|
|
+- 用户能够获得准确的错误信息,了解具体的失败原因
|
|
|
+- 避免了误导性的"系统繁忙"提示
|
|
|
+- 提高了API的可用性和调试友好性
|
|
|
+
|
|
|
+## 功能增强
|
|
|
+
|
|
|
+### ✅ 添加Validation验证机制
|
|
|
+根据您的建议,为CancelHandler添加了完整的Validation验证机制:
|
|
|
+
|
|
|
+#### 1. 创建MatchexchangeCancelValidation验证类
|
|
|
+- **文件路径**: `app/Module/AppGame/Validations/MatchexchangeCancelValidation.php`
|
|
|
+- **功能**: 规范化参数验证,与其他Handler保持一致
|
|
|
+- **验证规则**:
|
|
|
+ - 订单ID必须是大于0的整数
|
|
|
+ - 用户ID必须是大于0的整数
|
|
|
+ - 使用MexOrderExistsValidator进行订单存在性验证
|
|
|
+
|
|
|
+#### 2. 创建MexOrderExistsValidator验证器
|
|
|
+- **文件路径**: `app/Module/Mex/Validators/MexOrderExistsValidator.php`
|
|
|
+- **功能**: 验证订单存在性和可操作性
|
|
|
+- **验证内容**:
|
|
|
+ - 订单是否存在
|
|
|
+ - 订单是否属于当前用户
|
|
|
+ - 订单状态是否允许取消(只能取消PENDING状态的订单)
|
|
|
+ - 提供具体的状态描述信息
|
|
|
+
|
|
|
+#### 3. 重构CancelHandler
|
|
|
+- 使用`MatchexchangeCancelValidation::makeByProrobufUser($data)`创建验证对象
|
|
|
+- 调用`$validation->validated()`进行验证
|
|
|
+- 使用`$validation->getOrderId()`和`$validation->getUserId()`获取安全数据
|
|
|
+- 与AddHandler等其他Handler保持一致的验证模式
|
|
|
+
|
|
|
+### ✅ 验证功能测试
|
|
|
+1. **无效订单ID (0)**:返回"parameter id is required!"
|
|
|
+2. **不存在订单 (2)**:返回"订单不存在"
|
|
|
+3. **已取消订单 (6542)**:返回"只能取消等待中的订单,当前订单状态:已取消"
|
|
|
+4. **正常订单 (6414)**:成功取消,返回"订单取消成功"
|
|
|
+
|
|
|
+## 文件变更
|
|
|
+- `app/Module/AppGame/Handler/Matchexchange/CancelHandler.php` - 修复异常处理逻辑,添加Validation验证
|
|
|
+- `app/Module/AppGame/Validations/MatchexchangeCancelValidation.php` - 新增取消挂单验证类
|
|
|
+- `app/Module/Mex/Validators/MexOrderExistsValidator.php` - 新增订单存在性验证器
|
|
|
+
|
|
|
+## 提交信息
|
|
|
+
|
|
|
+### 第一次提交(异常处理修复)
|
|
|
+```
|
|
|
+修复Mex模块取消挂单Handler的异常处理逻辑
|
|
|
+
|
|
|
+- 修复CancelHandler中业务逻辑异常被当作系统异常处理的问题
|
|
|
+- 将订单不存在等业务错误正确返回VALIDATE_ERROR而非SERVER_ERROR
|
|
|
+- 区分LogicException和系统异常,提供更准确的错误信息
|
|
|
+- 修复响应对象设置错误,使用$this->response而非局部$response对象
|
|
|
+
|
|
|
+测试验证:
|
|
|
+- 不存在订单:返回VALIDATE_ERROR和具体错误信息
|
|
|
+- 正常取消:返回OK和成功信息
|
|
|
+```
|
|
|
+
|
|
|
+### 第二次提交(Validation机制)
|
|
|
+```
|
|
|
+为CancelHandler添加Validation验证机制
|
|
|
+
|
|
|
+- 创建MatchexchangeCancelValidation验证类,规范参数验证
|
|
|
+- 创建MexOrderExistsValidator验证器,验证订单存在性和可操作性
|
|
|
+- 重构CancelHandler使用Validation模式,与其他Handler保持一致
|
|
|
+- 增强验证功能:订单ID验证、用户权限验证、订单状态验证
|
|
|
+
|
|
|
+验证功能:
|
|
|
+- 订单ID必须是大于0的整数
|
|
|
+- 订单必须存在且属于当前用户
|
|
|
+- 只能取消状态为PENDING的订单
|
|
|
+- 提供具体的错误信息(如订单状态描述)
|
|
|
+
|
|
|
+测试验证:
|
|
|
+- 无效订单ID:返回参数验证错误
|
|
|
+- 不存在订单:返回订单不存在错误
|
|
|
+- 已取消订单:返回状态错误和具体描述
|
|
|
+- 正常订单:成功取消
|
|
|
+```
|
|
|
+
|
|
|
+## 相关文档
|
|
|
+- [Mex模块Handler文档](../2025年06月/12日0951-完成Mex模块相关Handler的创建.md)
|
|
|
+- [Mex模块取消挂单解冻修复](../202506/201759-修复Mex模块取消挂单没有解冻的问题.md)
|