Как избавиться от требования обработки исключения в Project Reactor?

Ссылка скопирована
1 ответ

В альтернативной реактивной либе RxJava обработка исключений помимо RuntimeException происходит в самом блоке, но в Project Reactor такого нет, неужели есть только один вариант это обрабатывать с поощью try/catch внутри каждого блока что бы избежать Unhandled exceptions? ниже привёл пример кода

private @NotNull Mono<JsonObject> invoke(Channel channel, Class<?> clazz, Method method, Object... args) {         return Mono.fromCallable(() -> clazz.getDeclaredConstructor(Server.class, Channel.class))                 .map(constructor -> constructor.newInstance(this.manager.getServer(), channel))                 .flatMap(obj -> new GenericData<JsonObject>().invoke(method, obj, args))                 .onErrorResume(Mono::error);     }

private @NotNull Mono<JsonObject> invoke(Channel channel, Class<?> clazz, Method method, Object... args) { return Mono.fromCallable(() -> clazz.getDeclaredConstructor(Server.class, Channel.class)) .map(constructor -> constructor.newInstance(this.manager.getServer(), channel)) .flatMap(obj -> new GenericData<JsonObject>().invoke(method, obj, args)) .onErrorResume(Mono::error); }

error: unreported exception InstantiationException; must be caught or declared to be thrown .map(constructor -> constructor.newInstance(this.manager.getServer(), channel))

error: unreported exception InstantiationException; must be caught or declared to be thrown .map(constructor -> constructor.newInstance(this.manager.getServer(), channel))

Дополнительно:

Тут проблема скорее в инстанцировании объекта, а не в реакторе

Ответы:

неужели есть только один вариант это обрабатывать с поощью try/catch внутри каждого блока что бы избежать Unhandled exceptions?

Вобщем-то да. Можно вынести try/catch в отдельный универсальный метод, который оборачивает исключение в RuntimeException:

private @NotNull Mono<JsonObject> invoke(Channel channel, Class<?> clazz, Method method, Object... args) {     return Mono.fromCallable(() -> clazz.getDeclaredConstructor(Server.class, Channel.class))         .map(constructor -> ex(() -> constructor.newInstance(this.manager.getServer(), channel)))         .flatMap(obj -> new GenericData<JsonObject>().invoke(method, obj, args))         .onErrorResume(Mono::error); }  private <T> T ex(Callable<T> code) {     try {         return code.call();     } catch (Exception e) {         throw new RuntimeException(e);     } }

private @NotNull Mono<JsonObject> invoke(Channel channel, Class<?> clazz, Method method, Object... args) { return Mono.fromCallable(() -> clazz.getDeclaredConstructor(Server.class, Channel.class)) .map(constructor -> ex(() -> constructor.newInstance(this.manager.getServer(), channel))) .flatMap(obj -> new GenericData<JsonObject>().invoke(method, obj, args)) .onErrorResume(Mono::error); } private <T> T ex(Callable<T> code) { try { return code.call(); } catch (Exception e) { throw new RuntimeException(e); } }

Конкретно в вашем примере можно вызов конструктора переместить в callable, из которого делается Mono, так как из Callable разрешено стрелять проверяемыми исключениями, в отличии от Function, который принимает map:

private @NotNull Mono<JsonObject> invoke(Channel channel, Class<?> clazz, Method method, Object... args) {     return Mono.fromCallable(() -> {             var constructor = clazz.getDeclaredConstructor(Server.class, Channel.class);             return constructor.newInstance(this.manager.getServer(), channel);         })         .flatMap(obj -> new GenericData<JsonObject>().invoke(method, obj, args))         .onErrorResume(Mono::error); }

private @NotNull Mono<JsonObject> invoke(Channel channel, Class<?> clazz, Method method, Object... args) { return Mono.fromCallable(() -> { var constructor = clazz.getDeclaredConstructor(Server.class, Channel.class); return constructor.newInstance(this.manager.getServer(), channel); }) .flatMap(obj -> new GenericData<JsonObject>().invoke(method, obj, args)) .onErrorResume(Mono::error); }

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Ольга Сеть Ответ

Для того чтобы избавиться от требования обработки исключения в Project Reactor, можно воспользоваться методом onErrorResume(), который позволяет обработать исключение и вернуть значение по умолчанию в случае ошибки.

Пример использования метода onErrorResume() в Reactor:

Flux.just(1, 2, 3)
    .map(i -> {
        if (i == 2) {
            throw new RuntimeException("Oops! Something went wrong");
        }
        return i;
    })
    .onErrorResume(e -> Flux.just(100, 200, 300)) // обработка исключения и возврат значений по умолчанию
    .subscribe(System.out::println);

Flux.just(1, 2, 3) .map(i -> { if (i == 2) { throw new RuntimeException("Oops! Something went wrong"); } return i; }) .onErrorResume(e -> Flux.just(100, 200, 300)) // обработка исключения и возврат значений по умолчанию .subscribe(System.out::println);

В данном примере, если при выполнении операции map() возникает исключение, то метод onErrorResume() обрабатывает это исключение и возвращает новый Flux с указанными значениями (100, 200, 300) вместо ошибочного значения.

Таким образом, использование метода onErrorResume() позволяет избежать необходимости обработки исключений в каждом операторе Flux'а и обеспечивает более гибкое управление ошибками в Reactor.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно