改进错误处理:避免异常被静默吞掉或未正确传播 - #4083
Conversation
- FileUtils.imageToBase64ByStream 读取失败时抛出 WxRuntimeException,不再 printStackTrace 后返回 null - AesUtils.HMACSHA256 签名计算失败时抛出 WxRuntimeException,不再返回 null 导致签名为空 - RequestUtils.readData 读取回调请求体失败时抛出异常,不再静默返回不完整内容 - PartnerTransferServiceImpl.spDayEndBalance 传播查询异常,不再返回 null - WxMpMemberCardServiceImpl.getActivatePluginParam 解析失败时抛出 WxErrorException - DefaultApacheHttpClientBuilder 空闲连接监控线程被中断时恢复中断标志 - 支付回调转换器、临时二维码文件删除、payBaseUrl 解析失败改为记录日志 新增 FileUtilsTest、AesUtilsTest 回归测试 Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
binarywang
left a comment
There was a problem hiding this comment.
感谢修复这些静默吞异常的路径。还有几处建议在合并前补齐:
-
AesUtils.HMACSHA256目前只捕获GeneralSecurityException | IllegalArgumentException。当data或key为null时,getBytes()会直接抛出NullPointerException,未按本 PR 的目标包装为WxRuntimeException。建议显式校验空参或统一包装运行时异常,并补充对应回归测试。 -
VerifierBuilder的 WARN 日志会输出完整payBaseUrl。该 URL 若含 query 参数,可能将 token、签名等敏感信息写入日志。建议仅记录脱敏后的地址(至少移除 query 和 user-info),或不记录原始 URL。 -
RequestUtils.readData与PartnerTransferServiceImpl.spDayEndBalance都修改了公共方法的异常语义,建议补充异常分支的单测:分别模拟request.getReader()抛出IOException、下游spDayEndBalance抛出WxPayException,断言包装后的异常类型和 cause。
Summary
排查各模块
main源码中被静默吞掉的异常(空catch、printStackTrace后返回null),改为向上传播或至少记录日志。重点是几个「失败时静默返回 null / 不完整数据」的路径,调用方无法区分成功与失败:FileUtils.imageToBase64ByStream:IOException之前被printStackTrace后返回null;现改为 try-with-resources 并抛出WxRuntimeException(同时修掉finally里再次吞异常的 close 逻辑)。AesUtils.HMACSHA256:签名计算失败返回null,会让createSign产出空签名后被当作正常请求发送;现抛出WxRuntimeException。RequestUtils.readData(V3 回调读取请求体):IOException被吞掉后返回已读到的部分内容,会导致验签/解析拿到截断报文;现抛出WxRuntimeException。PartnerTransferServiceImpl.spDayEndBalance:catch (Exception) { printStackTrace(); } return null;改为catch (WxPayException e) { throw new WxRuntimeException(e); },接口 Javadoc 同步修正(接口签名未加 checked 异常,保持源码/二进制兼容)。WxMpMemberCardServiceImpl.getActivatePluginParam:解析失败返回null改为抛WxErrorException(方法本就声明该异常)。DefaultApacheHttpClientBuilder空闲连接监控线程:catch (InterruptedException ignore) {}改为记录 debug 日志并Thread.currentThread().interrupt()恢复中断标志。以下场景的「继续执行」是有意为之,仅补日志、不改变行为:
WxPayOrderNotifyResultConverter.setFieldValue(单字段反射赋值失败)、WxMaCodeServiceImpl删除临时二维码文件失败、VerifierBuilder中payBaseUrl不是合法 URI、PublicCertificateVerifier平台证书验签失败降级为公钥验签。行为变更提示:上述前 5 处此前返回
null或不完整数据,现在会抛出未检查异常WxRuntimeException(WxErrorException处为已声明的受检异常);这是把原本被掩盖的失败暴露出来,未改变任何公共方法签名。测试
mvn -pl weixin-java-common,weixin-java-pay,weixin-java-mp,weixin-java-miniapp -am -DskipTests package:BUILD SUCCESS。FileUtilsTest#testImageToBase64ByStreamThrowsOnIoError、新增AesUtilsTest。仓库根 POM 中 surefire 被配置为<skip>true</skip>,故通过 TestNG 命令行在对应模块 classpath 下执行:FileUtilsTest4/4 通过,AesUtilsTest2/2 通过。Link to Devin session: https://app.devin.ai/sessions/0e0c592526ac4c158640d8f62c2a902a
Requested by: @binarywang