Feign错误解码器错误:请求处理失败;嵌套异常

问题描述 投票:0回答:1

我想为我的 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);
java spring exception error-handling feign
1个回答
0
投票

我发现处理 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 就这样了

© www.soinside.com 2019 - 2024. All rights reserved.