Перехват PrematureCloseException из WebClient, возвращающего поток - PullRequest
0 голосов
/ 18 июня 2020

Как я могу поймать reactor.netty.http.client.PrematureCloseException при использовании org.springframework.web.reactive.function.client.WebClient для извлечения и бесконечного reactor.core.publisher.Flux?

Чтобы воспроизвести проблему, я создал два тривиальных приложения Spring Boot. Оба основаны на org.springframework.boot:spring-boot-starter-webflux.

Код сервера:

@RestController
public class TestserverRestController {

    @GetMapping(value="/huge-flux", produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
    public Flux<Long> hugeFlux() {
        return Flux.range(1, Integer.MAX_VALUE).interval(Duration.ofSeconds(1));
    }

    @Autowired
    ConfigurableApplicationContext springContext;

    @GetMapping(value="/stop")
    public void stop() {
        springContext.close();
    }
}

Код клиента:

@Component
public class TestclientRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        Flux<Long> flux = WebClient.create().get()
                .uri("http://localhost:9000/huge-flux")
                .accept(MediaType.APPLICATION_STREAM_JSON)
                .retrieve()
                .bodyToFlux(Long.class);
        flux.subscribe(val -> System.out.printf("Value %d%n", val));
    }
}

При нажатии http://localhost:9000/stop в сети браузер клиент завершает работу, и эта ошибка появляется на консоли клиента.

WARN 15635 --- [ctor-http-nio-2] reactor.netty.channel.FluxReceive : [id: 0x82a94759, L:0.0.0.0/0.0.0.0:61812] An exception has been observed post termination, use DEBUG level to see the full stack: reactor.core.Exceptions$ErrorCallbackNotImplemented: reactor.netty.http.client.PrematureCloseException: Connection prematurely closed DURING response

Я хочу иметь возможность отловить эту ошибку, чтобы я мог ее исправить. (В моем реальном проекте будут альтернативные серверы для подключения, если один из них выйдет из строя.)

Вещи, которые я пробовал в клиенте, включают:

flux.doOnCancel(()-> log.warning("CANCEL"));
flux.doOnTerminate(()-> log.warning("TERMINATE"));
flux.doOnComplete(()-> log.warning("COMPLETE"));
flux.doOnDiscard(Object.class, (o)-> log.warning("DISCARD"));
flux.doOnError((e)-> log.warning("ERROR"));

, но ни одно из этих сообщений журнала не печатается когда сервер завершает работу.

1 Ответ

0 голосов
/ 19 июня 2020

Заменив строку flux.subsribe() в коде клиента на:

            flux.subscribe(
                    val -> System.out.printf("Value %d%n", val),
                    ex -> System.err.printf("ERROR CONSUMER [%s] %s", ex.getClass(), ex.getMessage()),
                    () -> System.err.printf("COMPLETE CONSUMER"));

, проблема может быть зафиксирована потребителем ошибки (вывод «ERROR CONSUMER»).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...