Try.of() 失败时如何抛出异常?
How to throw exception when Try.of() fails?
如果 Try.ofCallable()
失败,我想抛出从 Exception
扩展的异常。
我有一个可调用类型:
final Callable<MyResponse> decoratedCallable =
circuitBreakerService.getDecoratedMethod(
myArg1,
() -> myFunction(myArg1, myArg2, myArg3)
);
我正在尝试这样的事情:
Try.ofCallable(decoratedCallable).onFailure(throwable -> {
if (throwable instanceof CallNotPermittedException) {
throw new MyRuntimeExceptionA("msg1", throwable);
} else {
throw new MyRuntimeExceptionB("msg2", throwable);
}
});
如果 MyRuntimeExceptionA
和 MyRuntimeExceptionB
都扩展了 RuntimeException
,这将起作用(包装上述两个语句的函数抛出正确的异常 MyRuntimeExceptionA 和 MyRuntimeExceptionB),但如果它们扩展 Exception
.
如果它们扩展 Exception
那么我就不能将它们从主函数中抛出。
IDE 要求将它们包装在 try/catch 中——我不想要。
我不太了解 vavr,但是查看库的 javadoc,您可以看到 onFailure 方法采用 Consumer super Throwable> 作为参数。问题是消费者不声明已检查的异常,因此您永远无法从 lambda 中抛出已检查的异常。
也就是说,在这些情况下我通常做的是创建一个“包装”class 来接受已检查的异常,所有这些包装 class 将捕获所有已检查的异常并且将它们包装在运行时异常中。例如:
public class ThrowingConsumerHelper {
public static <T> Consumer<T> throwingConsumer(
ThrowingConsumer<T> consumer) {
return object -> {
try {
consumer.accept(object);
} catch (Throwable t) {
throw new RuntimeException(t);
}
};
}
@FunctionalInterface
public interface ThrowingConsumer<T> {
void accept(T t) throws Exception;
}
}
然后像这样使用:
import static ThrowingConsumerHelper.throwingConsumer;
public static void main(String[] args) {
onFailure(throwingConsumer(object -> { throw new Exception("Bug"); }));
}
public static void onFailure(Consumer<? super Throwable> consumer) {
// Do something
}
你有两个选择。当您尝试通过使用以下代码获取值来解包 Try
时,您可以抛出:
Try.ofCallable(decoratedCallable)
.getOrElseThrow(throwable -> {
if (throwable instanceof CallNotPermittedException) {
return new MyExceptionA("msg1", throwable);
} else {
return new MyExceptionB("msg2", throwable);
}
})
或者用类似的代码将错误映射代码移到解包之前:
Try.ofCallable(decoratedCallable)
.mapFailure(
Case(
$(instanceOf(CallNotPermittedException.class)),
throwable -> new MyExceptionA("msg1", throwable)
),
Case($(), throwable -> new MyExceptionB("msg2", throwable))
)
.get()
两种解决方案都只会在展开时抛出,所以如果你想早点抛出,你就得早点展开。
否则,如果您使用 Try
,我会采纳其他人在评论中发表的建议,不要抛出异常。使用 Try
的全部意义在于使用总函数而不是可能引发异常的部分函数。
如果 Try.ofCallable()
失败,我想抛出从 Exception
扩展的异常。
我有一个可调用类型:
final Callable<MyResponse> decoratedCallable =
circuitBreakerService.getDecoratedMethod(
myArg1,
() -> myFunction(myArg1, myArg2, myArg3)
);
我正在尝试这样的事情:
Try.ofCallable(decoratedCallable).onFailure(throwable -> {
if (throwable instanceof CallNotPermittedException) {
throw new MyRuntimeExceptionA("msg1", throwable);
} else {
throw new MyRuntimeExceptionB("msg2", throwable);
}
});
如果 MyRuntimeExceptionA
和 MyRuntimeExceptionB
都扩展了 RuntimeException
,这将起作用(包装上述两个语句的函数抛出正确的异常 MyRuntimeExceptionA 和 MyRuntimeExceptionB),但如果它们扩展 Exception
.
如果它们扩展 Exception
那么我就不能将它们从主函数中抛出。
IDE 要求将它们包装在 try/catch 中——我不想要。
我不太了解 vavr,但是查看库的 javadoc,您可以看到 onFailure 方法采用 Consumer super Throwable> 作为参数。问题是消费者不声明已检查的异常,因此您永远无法从 lambda 中抛出已检查的异常。
也就是说,在这些情况下我通常做的是创建一个“包装”class 来接受已检查的异常,所有这些包装 class 将捕获所有已检查的异常并且将它们包装在运行时异常中。例如:
public class ThrowingConsumerHelper {
public static <T> Consumer<T> throwingConsumer(
ThrowingConsumer<T> consumer) {
return object -> {
try {
consumer.accept(object);
} catch (Throwable t) {
throw new RuntimeException(t);
}
};
}
@FunctionalInterface
public interface ThrowingConsumer<T> {
void accept(T t) throws Exception;
}
}
然后像这样使用:
import static ThrowingConsumerHelper.throwingConsumer;
public static void main(String[] args) {
onFailure(throwingConsumer(object -> { throw new Exception("Bug"); }));
}
public static void onFailure(Consumer<? super Throwable> consumer) {
// Do something
}
你有两个选择。当您尝试通过使用以下代码获取值来解包 Try
时,您可以抛出:
Try.ofCallable(decoratedCallable)
.getOrElseThrow(throwable -> {
if (throwable instanceof CallNotPermittedException) {
return new MyExceptionA("msg1", throwable);
} else {
return new MyExceptionB("msg2", throwable);
}
})
或者用类似的代码将错误映射代码移到解包之前:
Try.ofCallable(decoratedCallable)
.mapFailure(
Case(
$(instanceOf(CallNotPermittedException.class)),
throwable -> new MyExceptionA("msg1", throwable)
),
Case($(), throwable -> new MyExceptionB("msg2", throwable))
)
.get()
两种解决方案都只会在展开时抛出,所以如果你想早点抛出,你就得早点展开。
否则,如果您使用 Try
,我会采纳其他人在评论中发表的建议,不要抛出异常。使用 Try
的全部意义在于使用总函数而不是可能引发异常的部分函数。