Quellcode durchsuchen

fix(进件): 存量 createShop 502 文案去掉上游名号(用户硬约束)

主控授权的越界:这处改动超出「Task 6 = 图片上传」的字面边界,但它撞的是用户的硬约束
「绝不暴露上游信息」—— 这条 BusinessException 经 GlobalExceptionHandler 是
Result.of(code, message),message **原样回给调用方**,所以它是会到达租户眼前的那一类串。

全模块实测只有这一处**会到达租户眼前且含上游名号**。LeshouyingApiException 自己那条
message 也含名号,但它走 LeshouyingOpenController 返回固定文案、兜底
@ExceptionHandler(Exception.class) 只回「服务器内部错误」⇒ 那一条**不泄漏**,不在本轮范围。
javadoc 里的名号不进 class、不到用户眼前,按裁定**保留**。

两个信息都保留:「接口回了成功但没有可用值」与「不得当作失败直接重试」(后者是行为指令)。
「成功」是真的 —— parseApi 对非 SUCCESS 一律抛 LeshouyingApiException,走得到这一行
就说明信封确实是 SUCCESS。

createShop_missingShopNo_throws 补一条断言:message 不含上游名号,与 upload 侧
assertUploadRejected400 的做法对称 —— 把约束从注释里的约定变成可执行的钉子。
只断言「不含名号」,**不逐字钉文案**:绿向变异实测过,只改这三条文案的措辞全量仍绿。

测试:全量 498,0 fail / 0 error / 0 skipped。
alphaH vor 3 Wochen
Ursprung
Commit
663156f4aa

+ 5 - 1
java/src/main/java/com/payment/platform/module/payment/leshouying/service/LsyOnboardingService.java

@@ -283,8 +283,12 @@ public class LsyOnboardingService {
 
         String shopNo = asText(client.postApi("/api/shop/create", p).get("shop_no"));
         if (StrUtil.isBlank(shopNo)) {
+            // 文案**不含上游名号**(Global Constraint 2):它经 GlobalExceptionHandler 原样回给调用方。
+            // 两个信息都保留:「接口回了成功但没有可用值」与「不得当作失败直接重试」(行为指令)。
+            // 「成功」是真的 —— parseApi 对非 SUCCESS 一律抛 LeshouyingApiException,
+            // 走得到这一行就说明信封确实是 SUCCESS(见 createShop 的 javadoc)。
             throw new BusinessException(502,
-                    "乐收赢返回成功但缺少门店号 shop_no(门店可能已在上游创建,不得当作失败直接重试)");
+                    "门店创建成功但缺少门店号 shop_no(门店可能已创建,不得当作失败直接重试)");
         }
         return shopNo;
     }

+ 8 - 0
java/src/test/java/com/payment/platform/module/payment/leshouying/service/LsyOnboardingServiceTest.java

@@ -705,6 +705,12 @@ class LsyOnboardingServiceTest {
      * <p>异常类型是**实现者裁定的**(brief 允许二选一),这里是
      * {@link BusinessException}(502):见 {@code LsyOnboardingService#createShop} 的 javadoc
      * 里那段「为什么不是 {@code LeshouyingApiException}」。
+     *
+     * <p>★ 另断言**文案不含上游名号**(用户硬约束):这条 {@link BusinessException} 走到
+     * {@code GlobalExceptionHandler} 时是 {@code Result.of(code, message)},
+     * message **原样回给调用方**,所以它是会到达租户眼前的那一类串。
+     * 与 upload 侧 {@code assertUploadRejected400} 的做法对称 —— 把约束从注释里的约定
+     * 变成可执行的钉子。**只断言「不含名号」,不逐字钉住文案**:钉死会让以后每次改标点都要动测试。
      */
     @Test
     void createShop_missingShopNo_throws() {
@@ -716,6 +722,8 @@ class LsyOnboardingServiceTest {
             BusinessException ex = assertThrows(BusinessException.class,
                     () -> service.createShop(validShopDto()), json + " ⇒ 必须抛,不得返回 null/空串");
             assertEquals(502, ex.getCode(), json);
+            assertFalse(ex.getMessage().contains("乐收赢"),
+                    json + " 的文案出现了上游名号(用户硬约束):" + ex.getMessage());
         }
     }