Spring Webflux Mono <Void> всегда отвечает успешным ответом

У меня есть конечная точка, которая принимает параметр id и отправляет api для удаления продукта для удаления. productService.delete также возвращает Mono. Проблема в том, что когда метод productService.delete возвращает моно-ошибку, конечная точка всегда отвечает http 200. И я могу видеть журнал ошибок об этой моно-ошибке, но мой метод-обработчик отвечает http 200.

У меня есть AbstractErrorWebExceptionHandler для обработки исключения в моем API. Но обработчик ошибок не может справиться с этой проблемой из-за Mono. Когда в нисходящем потоке возникают исключения, Spring webflux должен знать об этой ошибке и не отвечает с http 200.

    public Mono<ServerResponse> deleteProduct(ServerRequest request) {
     String id = request.pathVariable("id");
     Mono<Product> productMono = this.repository.findById(id);
     return productMono
            .flatMap(existingProduct ->
                    ServerResponse.noContent()
                            .build(productService.delete(existingProduct))
            );
}

Кстати, в исходном коде сказано, что ответ будет зафиксирован, когда данный издатель завершит работу. Но как насчет полной ошибки? Я думаю, что Spring webflux не проверяет, является ли это сигналом ошибки или нет. Просто проверьте, завершается ли моно или нет.

     * Build the response entity with no body.
     * The response will be committed when the given {@code voidPublisher} completes.
     * @param voidPublisher publisher publisher to indicate when the response should be committed
     * @return the built response
     */
    Mono<ServerResponse> build(Publisher<Void> voidPublisher);

Заранее спасибо.

1 ответ

Решение

Проблема вызвана использованием voidPublisher. Если вы создаете ServerResponse с void publisher, он просто вернет http 200, даже если ваш нисходящий поток завершен с сигналом ошибки. Его просто не волнует, как закончится ваш поток, он просто заботится о завершении нисходящего потока.

И если вы хотите обрабатывать последующую ошибку при создании своего ответа, просто используйте

 ServerResponse.noContent()
    .body(productService.delete(existingProduct), Void.class)

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

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