Вызов клиента 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 могла обрабатывать детали и двигаться вперед на основе этого.

Проблема в том, что когда я нажал на звонок из Сервиса А, используя

HTTP: // локальный: 8080 / симулировать / callServiceB

Служба 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

Другие вопросы по тегам