Fallback Factory не работает для обработки пользовательских исключений в Feign Client - PullRequest
2 голосов
/ 17 апреля 2020

Мое требование состоит в том, чтобы получить доступ к пользовательскому исключению, сгенерированному из первой службы, вместе с его содержимым тела во второй службе

До сих пор я пробовал 2 вещи, FallbackFactory и ErrorDecoder, из у меня только Fallback factory работал . У ошибки декодера не было сообщения об исключении, которое было сгенерировано другим сервисом. Вот пример кода, который я нашел в другом вопросе:

Будет 2 услуги: инвентарь-сервис и продукт-сервис

инвентарь-сервис

InventoryController. java

@RestController
@RequestMapping("/inventories")
public class InventoryController {

    private final ProductServiceClient productService;

    public InventoryController(ProductServiceClient productService) {
        super();
        this.productService = productService;
    }

    @GetMapping
    public ResponseEntity<?> companyInfo() {

        return productService.hello();

    }
}

ProductServiceClient. java

@FeignClient(name = "product-service", url = "http://localhost:9100", fallbackFactory = ProductServiceClientFallback.class)
public interface ProductServiceClient {

    @GetMapping("/products")
    ResponseEntity<?> hello();

}

@Component
class ProductServiceClientFallback implements FallbackFactory<ProductServiceClient> {

    @Override
    public ProductServiceClient create(Throwable cause) {

        return new ProductServiceClient() {

            @Override
            public ResponseEntity<?> hello() {
                System.out.println("hello!! fallback reason was " + cause.getMessage());
                return ResponseEntity.ok().build();
            }

        };
    }

}

product-service

ProductController. java

@RestController
@RequestMapping(value = "/products")
public class ProductController {

    @GetMapping
    public String hello() throws Exception {
        if (true) {
            throw new Exception("Service B Exception...");
        }
        return "Hello World";
    }
}

ProductControllerAdvice. java

@RestControllerAdvice
public class ProductControllerAdvice {
    @ExceptionHandler
    public ResponseEntity<?> handleException(Exception exception) {
        return new ResponseEntity<>("Caused due to : " + exception.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

Итак, когда / инвентаризации API запускается в контроллере инвентаризации, он запускает вызов на продукт-сервис через Feign Client и на стороне продукта-сервис, я выбрасываю пользовательское исключение с сообщением, я должен получить доступ к этому сообщению в моем Инвентаризация.

Для того, чтобы я реализовал резервную фабрику, и она работала в тестовом рабочем пространстве , так как я получил такой вывод в консоли инвентаризации

hello!! fallback reason was status 500 reading ProductServiceClient#hello(); content:
Caused due to : Service B Exception...

Но моя проблема заключается в том, что я пытаюсь подобный подход с приложениями, которые я работаю продолжая, я не получил сообщение об исключении, вместо этого я поставил выход, подобный этому :

reached fallback on workflow side, reason: status 400 reading ProvisioningServiceProxy#executeOrderAction(Long,Long,String)

Service-A

TestServiceA. java

@FeignClient( url = "/executeOrder", fallbackFactory = TestServiceAFallback.class )
public interface TestServiceA extends Serializable{
    @PostMapping( value = "order/{requestId}/order/{orderId}/{command}" )
    public ResponseEntity<ProcessInstanceVariable> executeOrderAction(                                                                            @PathVariable( name = "command" ) String command );
}

Service-B , из которого создается пользовательское исключение

TestServiceBController. java

@PostMapping( value = /executeOrder )
public ResponseEntity<ProcessInstanceVariable> executeOrderAction(                                                                      @PathVariable( value = "command" ) String command )
{  //switch code to check the command value and throw exception for one particular command
          throw new ValidationException("validation exception from service B");
}

У меня также есть совет, который обрабатывает исключения из валидации, и в этом классе есть такой метод

TestServiceBControllerAdvice. java

@ExceptionHandler( ValidationException.class )
public ResponseEntity<Object> handleValidationException( ValidationException ve )
{
    return new ResponseEntity<>( ve.getMessage(), HttpStatus.BAD_REQUEST );
}

Итак, я ожидал получить сообщение на стороне TestServiceA, которое я отправил от TestServiceB, но я получил общее сообщение c, показывающее, что BAD REQUEST при чтении API.

I ' Я не уверен, требуется ли какая-либо дополнительная конфигурация на стороне TestServiceA, кроме конфигурации ниже:

testServiceA.properties

feign.hystrix.enabled=true

Дайте мне знать, если что-то отсутствует в моем В конце концов, я прошел эту документацию и мне кажется, я выполнили реализацию так, как это должно было случиться, чтобы получить сообщение и тело исключения, выданные другим сервисом.

...