改进错误处理:避免异常被静默吞掉
- 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>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package me.chanjar.weixin.common.util.fs;
|
||||
|
||||
import me.chanjar.weixin.common.error.WxRuntimeException;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import java.io.File;
|
||||
@@ -55,24 +56,16 @@ public class FileUtils {
|
||||
*
|
||||
* @param in 文件流
|
||||
* @return base64编码
|
||||
* @throws WxRuntimeException 读取文件流失败时抛出
|
||||
*/
|
||||
public static String imageToBase64ByStream(InputStream in) {
|
||||
// 读取图片字节数组
|
||||
try {
|
||||
try (InputStream input = in) {
|
||||
// 返回Base64编码过的字节数组字符串
|
||||
return Base64.getEncoder().encodeToString(IOUtils.toByteArray(in));
|
||||
return Base64.getEncoder().encodeToString(IOUtils.toByteArray(input));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
throw new WxRuntimeException(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -318,7 +318,9 @@ public class DefaultApacheHttpClientBuilder implements ApacheHttpClientBuilder {
|
||||
TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException ignore) {
|
||||
} catch (InterruptedException e) {
|
||||
log.debug("空闲连接监控线程被中断,退出监控", e);
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package me.chanjar.weixin.common.util.fs;
|
||||
|
||||
import me.chanjar.weixin.common.error.WxRuntimeException;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@@ -13,6 +14,7 @@ import java.util.Base64;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
public class FileUtilsTest {
|
||||
|
||||
@@ -59,4 +61,17 @@ public class FileUtilsTest {
|
||||
String result = FileUtils.imageToBase64ByStream(chunked);
|
||||
assertThat(result).isEqualTo(Base64.getEncoder().encodeToString(original));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImageToBase64ByStreamThrowsOnIoError() {
|
||||
InputStream failing = new InputStream() {
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
throw new IOException("read failed");
|
||||
}
|
||||
};
|
||||
assertThatThrownBy(() -> FileUtils.imageToBase64ByStream(failing))
|
||||
.isInstanceOf(WxRuntimeException.class)
|
||||
.hasCauseInstanceOf(IOException.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import cn.binarywang.wx.miniapp.json.WxMaGsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.error.WxError;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor;
|
||||
@@ -29,6 +30,7 @@ import static cn.binarywang.wx.miniapp.constant.WxMaApiUrlConstants.Code.*;
|
||||
* @author <a href="https://github.com/charmingoh">Charming</a>
|
||||
* @since 2018-04-26 20:00
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class WxMaCodeServiceImpl implements WxMaCodeService {
|
||||
private final WxMaService service;
|
||||
@@ -60,7 +62,8 @@ public class WxMaCodeServiceImpl implements WxMaCodeService {
|
||||
try {
|
||||
// 及时删除二维码文件,避免积压过多缓存文件
|
||||
Files.delete(qrCodeFilePath);
|
||||
} catch (Exception ignored) {
|
||||
} catch (Exception e) {
|
||||
log.warn("删除临时二维码文件失败,path={}", qrCodeFilePath, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.error.WxError;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.common.util.json.WxGsonBuilder;
|
||||
import me.chanjar.weixin.mp.api.WxMpMemberCardService;
|
||||
@@ -253,9 +254,8 @@ public class WxMpMemberCardServiceImpl implements WxMpMemberCardService {
|
||||
activatePluginParam.setBiz(resultMap.get("biz") + "==");
|
||||
return activatePluginParam;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
throw new WxErrorException(WxError.builder().errorMsg("解析激活插件参数失败:" + e.getMessage()).build(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.github.binarywang.wxpay.exception.WxPayException;
|
||||
import com.github.binarywang.wxpay.v3.auth.*;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.net.URI;
|
||||
@@ -17,6 +18,7 @@ import java.security.PublicKey;
|
||||
*
|
||||
* @author holy
|
||||
*/
|
||||
@Slf4j
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
class VerifierBuilder {
|
||||
/**
|
||||
@@ -127,8 +129,8 @@ class VerifierBuilder {
|
||||
if (StringUtils.isNotBlank(rawPath) && !"/".equals(rawPath)) {
|
||||
signUriStripPrefix = rawPath;
|
||||
}
|
||||
} catch (URISyntaxException ignored) {
|
||||
// ignore
|
||||
} catch (URISyntaxException e) {
|
||||
log.warn("payBaseUrl不是合法的URI,将不使用签名前缀剪裁,payBaseUrl={}", payBaseUrl, e);
|
||||
}
|
||||
}
|
||||
return new AutoUpdateCertificatesVerifier(
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
|
||||
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
|
||||
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
|
||||
import com.thoughtworks.xstream.mapper.Mapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
@@ -26,6 +27,7 @@ import java.util.Map;
|
||||
*
|
||||
* @author aimilin
|
||||
*/
|
||||
@Slf4j
|
||||
public class WxPayOrderNotifyResultConverter extends AbstractReflectionConverter {
|
||||
|
||||
/**
|
||||
@@ -116,7 +118,8 @@ public class WxPayOrderNotifyResultConverter extends AbstractReflectionConverter
|
||||
PropertyDescriptor pd = new PropertyDescriptor((String) field.getName(), obj.getClass());
|
||||
pd.getWriteMethod().invoke(obj, val);
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
} catch (Exception e) {
|
||||
log.warn("支付回调报文字段赋值失败,field={}", field.getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -195,7 +195,7 @@ public interface PartnerTransferService {
|
||||
* @param accountType 服务商账户类型
|
||||
* @param date 查询日期 2020-09-11
|
||||
* @return 返回数据 fund balance result
|
||||
* @throws WxPayException the wx pay exception
|
||||
* @throws me.chanjar.weixin.common.error.WxRuntimeException 查询失败时抛出,具体原因参见 cause
|
||||
*/
|
||||
FundBalanceResult spDayEndBalance(SpAccountTypeEnum accountType, String date);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.github.binarywang.wxpay.exception.WxPayException;
|
||||
import com.github.binarywang.wxpay.service.PartnerTransferService;
|
||||
import com.github.binarywang.wxpay.service.WxPayService;
|
||||
import com.github.binarywang.wxpay.v3.util.RsaCryptoUtil;
|
||||
import me.chanjar.weixin.common.error.WxRuntimeException;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import jodd.util.StringUtil;
|
||||
@@ -315,16 +316,15 @@ public class PartnerTransferServiceImpl implements PartnerTransferService {
|
||||
* @param accountType 服务商账户类型
|
||||
* @param date 查询日期 2020-09-11
|
||||
* @return 返回数据 fund balance result
|
||||
* @throws WxPayException the wx pay exception
|
||||
* @throws WxRuntimeException 查询失败时抛出,具体原因参见 cause
|
||||
*/
|
||||
@Override
|
||||
public FundBalanceResult spDayEndBalance(SpAccountTypeEnum accountType, String date) {
|
||||
try {
|
||||
return this.payService.getEcommerceService().spDayEndBalance(accountType, date);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} catch (WxPayException e) {
|
||||
throw new WxRuntimeException(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.github.binarywang.wxpay.util;
|
||||
|
||||
import me.chanjar.weixin.common.error.WxRuntimeException;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
@@ -19,12 +21,11 @@ public class RequestUtils {
|
||||
*
|
||||
* @param request HTTP请求对象
|
||||
* @return 字符串
|
||||
* @throws WxRuntimeException 读取请求体失败时抛出
|
||||
*/
|
||||
public static String readData(HttpServletRequest request) {
|
||||
BufferedReader br = null;
|
||||
StringBuilder result = new StringBuilder();
|
||||
try {
|
||||
br = request.getReader();
|
||||
try (BufferedReader br = request.getReader()) {
|
||||
for (String line; (line = br.readLine()) != null; ) {
|
||||
if (result.length() > 0) {
|
||||
result.append("\n");
|
||||
@@ -32,15 +33,7 @@ public class RequestUtils {
|
||||
result.append(line);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
throw new WxRuntimeException("读取请求体失败", e);
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
|
||||
@@ -3,8 +3,10 @@ package com.github.binarywang.wxpay.v3.auth;
|
||||
import java.security.*;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Base64;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.error.WxRuntimeException;
|
||||
|
||||
@Slf4j
|
||||
public class PublicCertificateVerifier implements Verifier{
|
||||
|
||||
private final PublicKey publicKey;
|
||||
@@ -32,6 +34,7 @@ public class PublicCertificateVerifier implements Verifier{
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 证书验证失败,继续尝试公钥验证
|
||||
log.debug("平台证书验签失败,降级为公钥验签,serialNumber={}", serialNumber, e);
|
||||
}
|
||||
}
|
||||
// 使用公钥验证(兜底方案,适用于公钥转账等场景)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.github.binarywang.wxpay.v3.util;
|
||||
|
||||
import me.chanjar.weixin.common.error.WxRuntimeException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
@@ -123,9 +124,8 @@ public class AesUtils {
|
||||
sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
|
||||
}
|
||||
return sb.toString().toUpperCase();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} catch (GeneralSecurityException | IllegalArgumentException e) {
|
||||
throw new WxRuntimeException("HMAC-SHA256签名计算失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.github.binarywang.wxpay.v3.util;
|
||||
|
||||
import me.chanjar.weixin.common.error.WxRuntimeException;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
/**
|
||||
* 测试 {@link AesUtils}.
|
||||
*/
|
||||
public class AesUtilsTest {
|
||||
|
||||
@Test
|
||||
public void testHmacSha256() {
|
||||
assertThat(AesUtils.HMACSHA256("data", "key")).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHmacSha256ThrowsOnInvalidKey() {
|
||||
// 空密钥无法构造 SecretKeySpec,此前该场景会被静默吞掉并返回 null
|
||||
assertThatThrownBy(() -> AesUtils.HMACSHA256("data", ""))
|
||||
.isInstanceOf(WxRuntimeException.class);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user