我们可以在回退或回退工厂中抛出异常吗@FeignClient



我正在使用@FeignClient,并希望在Feign抛出异常然后将结果回复到前端时执行一些逻辑(例如记录异常信息(。

我注意到Feign会在连接失败或http状态不期望时抛出FeignException。

所以我定义了一个@ExceptionHandler,以便在调用回调方法后捕获 FeignException。

@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的回调或回调工厂时,它无法捕获。

@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;
}
};
}
}

我注意到了,因为hystrix接管了这种方法。并将在 HystrixInvocationHandler 中捕获异常。

try {
Object fallback = HystrixInvocationHandler.this.fallbackFactory.create(this.getExecutionException());
Object result = ((Method)HystrixInvocationHandler.this.fallbackMethodMap.get(method)).invoke(fallback, args);
if (HystrixInvocationHandler.this.isReturnsHystrixCommand(method)) {
return ((HystrixCommand)result).execute();
} else if (HystrixInvocationHandler.this.isReturnsObservable(method)) {
return ((Observable)result).toBlocking().first();
} else if (HystrixInvocationHandler.this.isReturnsSingle(method)) {
return ((Single)result).toObservable().toBlocking().first();
} else if (HystrixInvocationHandler.this.isReturnsCompletable(method)) {
((Completable)result).await();
return null;
} else {
return HystrixInvocationHandler.this.isReturnsCompletableFuture(method) ? ((Future)result).get() : result;
}
} catch (IllegalAccessException var3) {
throw new AssertionError(var3);
} catch (ExecutionException | InvocationTargetException var4) {
throw new AssertionError(var4.getCause());
} catch (InterruptedException var5) {
Thread.currentThread().interrupt();
throw new AssertionError(var5.getCause());
}

所以我想知道当我使用回调/回调工厂时如何抛出异常,或者有另一种方法代替回调工厂来执行"回调"?

非常感谢

我找到了这个问题的解决方案。

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;
}
};
}
}

然后捕获 HystrixRuntimeException 并在 ExceptionHandler 中获取异常原因,以获取由 Hystrix 包装的 realException。

@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);
}

但我不认为这是一个好办法~

我从来没有在回退中这样做过,我已经实现了自定义错误解码器("CustomFeignErrorDecoder"(类和扩展的feign.codec.ErrorDecoder,每次发生错误时都会出现在这个类中。

解码函数中抛出一个自定义异常,并在控制器或服务层中捕获它,以向前端显示你的消息。

例:

@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());
}
}

相关内容

  • 没有找到相关文章