Вызов клиента Spring Feign входит в блок исключений, когда он должен оставаться в блоке try
Нужна небольшая помощь о клиенте Spring Feign. Итак, вот ситуация,
У меня есть 2 службы загрузки Spring. Допустим, Сервис A и Сервис B. Я настроил свой Сервис A с клиентом Feign, через который я вызываю метод Сервис B.
Так вот код для моей службы А,
Мой интерфейс конфигурации FeignCleint,
@FeignClient(name = "FeignClient", url = "http://localhost:8081/ServiceB/hello")
public interface FeignApi {
@RequestMapping(method = RequestMethod.GET)
ResponseEntity<?> hello();
}
И мой контроллер покоя, который использует вышеупомянутый feign config для вызова метода Service B,
@RestController
public class ApiController {
@Autowired
private FeignApi feignApi;
@RequestMapping(value = "/callServiceB")
public ResponseEntity<?> companyInfo() {
ResponseEntity<?> response = new ResponseEntity("OK Response", HttpStatus.OK);
try {
response = feignApi.hello();
// Code for some other things related to application.
return response;
} catch (Exception ex) {
System.out.println("Service A Exception block reached.");
return new ResponseEntity(ex.getMessage(), HttpStatus.BAD_REQUEST);
}
}
}
ниже мой контроллер для службы B,
@RestController
public class MyController {
@GetMapping("/hello")
public String hello() throws Exception {
if (true) {
throw new Exception("Service B Exception...");
}
return "Hello World";
}
}
И мой совет контроллера по обработке исключения, которое я выкидываю вручную,
@ControllerAdvice
public class MyControllerAdvice {
@ExceptionHandler
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseEntity<?> handleException(Exception exception, Model model) {
return new ResponseEntity<>("Caused due to : " + exception.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Теперь мой поток такой, как показано ниже. Как видите, я вызываю службу B из службы A с использованием симулированного клиента. Моя служба B генерирует исключение вручную, которое я перехватываю, используя рекомендации контроллера, и отправляю детали исключения в качестве ResponseEntity обратно в вызывающую службу A. Чтобы служба A могла обрабатывать детали и двигаться вперед на основе этого.
Проблема в том, что когда я нажал на звонок из Сервиса А, используя
Служба B дает сбой, как и ожидалось. Теперь я ожидаю, что Служба A должна получить ответ обратно в форме ResponseEntity. Но в действительности происходит то, что поток входит в блок исключений, а не остается в блоке try. Я вижу эту строку напечатанной,
"Service A Exception block reached."
Это то, что я не понимаю. Если я справился с исключением службы B, используя рекомендации контроллера, и отправил ответ службе A в форме ResponseEntity, то как поток службы A входит в блок перехвата. Я ожидаю, что он останется в блоке try, так как я хочу продолжить обработку на основе данных.
Любая идея, как я могу обойти эту вещь? Или это так, даже если я использую совет контроллера для управления исключениями? Каким должно быть ожидаемое поведение в этом случае?
Пожалуйста посоветуй.
1 ответ
По умолчанию Feign выбрасывает FeignException для любой ошибки. Используйте резервный механизм для обработки сбоев.
@FeignClient(name = "FeignClient", url = "http://localhost:8081/ServiceB/hello", fallback= FeignApiFallback.class)
public interface FeignApi {
@RequestMapping(method = RequestMethod.GET)
ResponseEntity<?> hello();
}
@Component
class FeignApiFallback implements FeignApi {
@Override
public ResponseEntity<?> hello() {
//do more logic here
return ResponseEntity.ok().build();
}
}
убедитесь, что вы добавили свойство ниже для переноса методов в командах Hystrix в последних выпусках
feign.hystrix.enabled=true
Любой статус кроме 200, симулируемый клиент будет рассматривать это как исключение, и вы устанавливаете HttpStatus.INTERNAL_SERVER_ERROR в своем совете контроллера.
Вы можете использовать собственный ErrorDecoder
см. https://github.com/OpenFeign/feign/wiki/Custom-error-handling