我想为我的 Feign 客户端创建一个错误处理程序,因此我创建了一个 CustomErrorDecoder,更新了 Feign 配置以使用这个新的错误解码器,创建了自定义异常,最后抛出了异常。但是,当抛出异常时,我收到此错误,并且我不知道问题是什么。这是错误消息:
请求处理失败;嵌套异常是 fr.application.configuration.exceptions.NotFoundException:错误 发生。 error.already_close_or_unknown 位于 org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) 〜[spring-webmvc-5.3.9.jar:5.3.9] 在 org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) 〜[spring-webmvc-5.3.9.jar:5.3.9]
这是错误解码器:
public class CustomErrorDecoder implements ErrorDecoder {
private final ErrorDecoder defaultErrorDecoder = new Default();
@Override
public Exception decode(String methodKey, Response response) {
ErrorMessage message;
try (InputStream bodyIs = response.body()
.asInputStream()) {
ObjectMapper mapper = new ObjectMapper();
message = mapper.readValue(bodyIs, ErrorMessage.class);
} catch (IOException e) {
return new Exception(e.getMessage());
}
return switch (response.status()) {
case 400 -> new BadRequestException(message.getMessage() != null ? message.getMessage() : "Bad Request");
case 404 -> new NotFoundException(message.getErrorCode() != null ? message.getErrorCode() : "Not found");
default -> defaultErrorDecoder.decode(methodKey, response);
};
}
}
feign的配置:
private static <T> T createClient(Class<T> clientClass, String baseUrl) {
BUSINESS_LOGGER.info("Creating client for class {} with base URL {}", clientClass, baseUrl);
return Feign.builder()
.encoder(new JacksonEncoder())
.decoder(new JacksonDecoder())
.errorDecoder(new CustomErrorDecoder())
.logger(new Slf4jLogger(clientClass))
.logLevel(feign.Logger.Level.FULL)
.target(clientClass, baseUrl);
}
这就是我抛出异常的方式
try {
return apiClient.endPoint(Url,
body);
} catch (NotFoundException | BadRequestException | InternalServerErrorException e) {
BUSINESS_LOGGER.error( e.getMessage());
throw e;
}
以及我的假客户的 endPint
@RequestLine("POST {endpoint}")
@Headers({
"Content-Type: application/json",
})
ObjectDto endPoint( @Param("endpoint") String endpoint, ObjectDto object);
我发现处理 Feign 客户端错误只需使用像这样的异常处理程序即可完成,而不需要配置 ErrorDecoder
@ExceptionHandler(FeignException.class)
public ErrorMessage handleFeignException(FeignException feignException, WebRequest webRequest){
String requestPath = ((ServletWebRequest) webRequest).getRequest().getRequestURI();
ObjectMapper objectMapper = new ObjectMapper();
int statusCode = feignException.status();
String content = feignException.contentUTF8();
if (content != null && content.trim().startsWith("{")) {
JsonNode jsonNode = objectMapper.readTree(content);
if(Objects.nonNull(jsonNode.get("error_code"))) {
String errorMessage = jsonNode.get("error_code").toString();
return new ErrorMessage(errorMessage, statusCode, requestPath);
}
if(Objects.nonNull(jsonNode.get("message"))) {
String errorMessage = jsonNode.get("message").toString();
return new ErrorMessage(errorMessage, statusCode, requestPath);
}
} else {
return new ErrorMessage("Invalid response format, not JSON", HttpStatus.PRECONDITION_FAILED.value(), requestPath);
}
return new ErrorMessage("Unknown error occurred", HttpStatus.PRECONDITION_FAILED.value(), requestPath);
}
使用 errorCode errorMessage 和路径创建了一个 ErrorMessage pojo 就这样了