Spring cloud 我们可以在@FeignClient的fallback或fallbackFactory中抛出异常吗
我正在使用@FeignClient,希望在Feign抛出异常时执行一些逻辑(比如记录异常信息),然后将结果回复到前端 我注意到当连接失败或http状态不符合预期时,Faign将抛出FaignException 因此,我定义了@ExceptionHandler,以在调用回调方法后捕获假异常Spring cloud 我们可以在@FeignClient的fallback或fallbackFactory中抛出异常吗,spring-cloud,hystrix,spring-cloud-feign,feign,Spring Cloud,Hystrix,Spring Cloud Feign,Feign,我正在使用@FeignClient,希望在Feign抛出异常时执行一些逻辑(比如记录异常信息),然后将结果回复到前端 我注意到当连接失败或http状态不符合预期时,Faign将抛出FaignException 因此,我定义了@ExceptionHandler,以在调用回调方法后捕获假异常 @ExceptionHandler(value = FeignException.class) @ResponseBody public ResponseResult feignExce
@ExceptionHandler(value = FeignException.class)
@ResponseBody
public ResponseResult feignException(FeignException exception){
String message = exception.getMessage();
byte[] content = exception.content();
int status = exception.status();
if(content!=null){
String response=new String(content);
message=String.format("%s response message : %s",message,response);
}
log.warn("{} : {} , cause by : {}",exception.getClass().getSimpleName(),message,exception.getCause());
return ResponseResult.fail(HttpStatus.valueOf(status),String.format("9%s00",status),message);
但是当我设置@FeignClient的callback或callbackFactory时,它无法捕获
@FeignClient(url = "${onboardingcase.uri}",name = "OnBoardingCaseService",
fallbackFactory = OnBoardingCaseServiceFallBack.class)
@Component
@Slf4j
public class OnBoardingCaseServiceFallBack implements FallbackFactory<OnBoardingCaseService> {
@Override
public OnBoardingCaseService create(Throwable throwable) {
return new OnBoardingCaseService() {
@Override
public OnBoardingCaseVo query(String coid) {
if(throwable instanceof FeignException){
throw (FeignException)throwable;
}
return null;
}
};
}
}
所以我想知道,当我使用callback/callbackFactory时,如何抛出异常,或者有另一种方法代替callbackFactory来执行“回调”
非常感谢我从来没有在回退中这样做过,我实现了自定义错误解码器(“CustomFeignErrorCoder”)类,并对其进行了扩展,每次出现错误时,它都会出现在这个类中 在解码函数中,抛出一个自定义异常,并在控制器或服务层捕获它,以便将消息显示到前端 例如:
@Component
public class CustomFeignErrorDecoder implements ErrorDecoder {
@Override
public Exception decode(String methodKey, Response response) {
throw new CustomFeignErrorDecoderException(methodKey +" response status "+ response.status() +" request "+ response.request()+ " method "+ response.request().httpMethod());
}
}
我找到了解决这个问题的办法
public class OnBoardingCaseServiceFallBack implements FallbackFactory<OnBoardingCaseService> {
@Override
public OnBoardingCaseService create(Throwable throwable) {
return new OnBoardingCaseService() {
@Override
public OnBoardingCaseVo query(String coid) {
log.error("OnBoardingCaseService#query fallback , exception",throwable);
if(throwable instanceof FeignException){
throw (FeignException)throwable;
}
return null;
}
};
}
}
但我认为这不是一个好办法~谢谢帕万。我像您一样插入了errorDecoder,但是我发现这个过程是CustomErrorDecoder->callback方法(如果实现了回调方法)。如果我们在回调方法上抛出异常,它将被HystrixRuntimeException包装。然后我可以得到我自定义的异常。我添加了实现,如果您共享我可以在本地复制的最小代码以查看问题的话,可以尝试添加Hystix属性“TimeoutinMissels”。当HystrixCommand失败时抛出的RuntimeException,并且根据Yes Pavan没有回退。因此,我的设计是在回退方法上抛出一个自定义异常。然后使用@ExceptionHandler(value=HystrixRuntimeException.class)捕获HystrixRuntimeException。我可以在HystrixRuntimeException中获取自定义异常。你怎么认为?这是不是一个好方法?我在另一个答案中显示了代码。你可以把这一页拉下来检查一下。thanksI也是这样做的,但非癔症异常只是一个带有Async+Feign的常规检查异常
public class OnBoardingCaseServiceFallBack implements FallbackFactory<OnBoardingCaseService> {
@Override
public OnBoardingCaseService create(Throwable throwable) {
return new OnBoardingCaseService() {
@Override
public OnBoardingCaseVo query(String coid) {
log.error("OnBoardingCaseService#query fallback , exception",throwable);
if(throwable instanceof FeignException){
throw (FeignException)throwable;
}
return null;
}
};
}
}
@ExceptionHandler(value = HystrixRuntimeException.class)
@ResponseBody
public ResponseResult hystrixRuntimeException(HystrixRuntimeException exception){
Throwable fallbackException = exception.getFallbackException();
Throwable assertError = fallbackException.getCause();
Throwable realException = assertError.getCause();
if(realException instanceof FeignException){
FeignException feignException= (FeignException) realException;
String message = feignException.getMessage();
byte[] content = feignException.content();
int status = feignException.status();
if(content!=null){
String response=new String(content);
message=String.format("%s response message : %s",message,response);
}
return ResponseResult.fail(HttpStatus.valueOf(status),String.format("9%s00",status),message);
}
String message = exception.getMessage();
log.warn("{} : {} , cause by : {}",exception.getClass().getSimpleName(),message,exception.getCause());
return ResponseResult.fail(ResultCode.FAIL.httpStatus(),ResultCode.FAIL.code(),message);
}