fix(file): 透出 IAM 资质登记的真实业务错误,避免误报为服务不可用

- 当 IAM 返回 4xx 业务拒绝(如资质已审核通过、企业不存在)时,解析响应体中的 message 并透传给前端
- 补充 WARN 和 ERROR 日志,记录 Feign 异常的 status 和 body,便于排查
- 移除硬编码的在审核中提示,改为根据 IAM 实际返回的状态码和消息动态映射
This commit is contained in:
2026-07-31 17:54:41 +08:00
parent 8287bc1da2
commit e834482717
@@ -6,8 +6,11 @@ import com.baiyue.common.core.exception.BizException;
import com.baiyue.common.security.AuthenticatedUser;
import com.baiyue.file.client.IamQualificationClient;
import com.baiyue.file.service.LocalQualificationStorage;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.FeignException;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.CacheControl;
import org.springframework.http.MediaType;
@@ -20,8 +23,10 @@ import org.springframework.web.multipart.MultipartFile;
@RestController
@RequestMapping("/api/merchant/v1/files/qualifications")
public class QualificationFileController {
private static final Logger LOGGER = LoggerFactory.getLogger(QualificationFileController.class);
@Resource private LocalQualificationStorage storage;
@Resource private IamQualificationClient iamClient;
@Resource private ObjectMapper objectMapper;
@Value("${baiyue.security.internal-service-token}") private String internalToken;
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@@ -44,14 +49,36 @@ public class QualificationFileController {
data.tenantStatus(), stored.documentUrl()));
} catch (RuntimeException exception) {
storage.delete(stored);
if (exception instanceof FeignException feign && feign.status() == 409) {
throw new BizException(ResultCode.CONFLICT, "Enterprise information is already under review");
}
if (exception instanceof BizException business) throw business;
if (exception instanceof FeignException feign) {
LOGGER.warn("IAM 资质登记被拒绝:status={} body={}", feign.status(), feign.contentUTF8());
if (feign.status() >= 400 && feign.status() < 500) {
throw new BizException(resultCodeOf(feign.status()), iamMessage(feign));
}
}
LOGGER.error("IAM 资质登记调用失败", exception);
throw new BizException(ResultCode.SERVICE_UNAVAILABLE, "IAM qualification service is unavailable");
}
}
/** 透出 IAM 返回的业务错误消息,避免把"已审核通过""重复提交"等业务拒绝误报为服务不可用。 */
private String iamMessage(FeignException feign) {
try {
String message = objectMapper.readTree(feign.contentUTF8()).path("message").asText(null);
if (message != null && !message.isBlank()) return message;
} catch (Exception ignored) { }
return "Enterprise qualification submission was rejected";
}
private ResultCode resultCodeOf(int status) {
return switch (status) {
case 403 -> ResultCode.FORBIDDEN;
case 404 -> ResultCode.NOT_FOUND;
case 409 -> ResultCode.CONFLICT;
default -> ResultCode.BUSINESS_ERROR;
};
}
@GetMapping("/{fileName}")
public ResponseEntity<org.springframework.core.io.Resource> download(
@AuthenticationPrincipal AuthenticatedUser user, @PathVariable String fileName) {