@AdaMorgan

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

В альтернативной реактивной либе 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);
    }

error: unreported exception InstantiationException; must be caught or declared to be thrown
.map(constructor -> constructor.newInstance(this.manager.getServer(), channel))
  • Вопрос задан
  • 57 просмотров
Решения вопроса 1
Vamp
@Vamp
неужели есть только один вариант это обрабатывать с поощью 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);
    }
}


Конкретно в вашем примере можно вызов конструктора переместить в 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);
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы