英文:
Is a method that returns a Try allowed to throw?
问题
我们在项目中使用Vavr来简化异常处理。我总是确保一个返回 Try
的方法不会抛出任何异常,就像这样:
public Try<Result> someSafeMethod() {
return Try.of(() -> someService.generateId())
.map(someOtherService::getValueForId)
.map(mappingService::mapToResult);
}
但是我的一些同事可能会这样实现:
public Try<Result> someSafeMethod() {
String generatedId = someService.generateId(); // <- 可能会抛出未在 Try 语句中捕获的异常
return Try.of(() -> someOtherService.getValueForId(generatedId))
.map(mappingService::mapToResult);
}
他们认为,如果生成ID出现问题,他们宁愿抛出异常,而不是返回的 Try
失败。
文档没有禁止返回 Try
的方法抛出异常,但它确实声明了:
> Try 是一种单子容器类型,表示可能会导致异常或返回成功计算值的计算。
我是否过于严格?想象一下,如果您使用的 API 中的所有方法都返回 Try
,当它们仍然抛出异常时,这是否会很糟糕?
英文:
We're using Vavr in our project to ease exception handling. I always make sure that a method that returns a Try
can never throw anything, like so:
public Try<Result> someSafeMethod() {
return Try.of(() -> someService.generateId())
.map(someOtherService::getValueForId)
.map(mappingService::mapToResult);
}
but some of my colleagues would implement it like this:
public Try<Result> someSafeMethod() {
String generatedId = someService.generateId(); // <- Might throw an Exception that is not caught by the Try clause
return Try.of(() -> someOtherService.getValueForId(generatedId))
.map(mappingService::mapToResult);
}
Arguing that if something is wrong with the generation of the ID that they would rather the exception is thrown instead of the returned Try
being a failure.
The documentation does not prohibit that a method returning a Try
should not throw, but it does state that:
> Try is a monadic container type which represents a computation that may either result in an exception, or return a successfully computed value.
Am I being too too strict? Imagine you would use an API where all methods return a Try
, wouldn't it be bad when they still throw?
答案1
得分: 3
你没有太过严格。
将Try
用作返回值的整个要点在于使用总函数进行编程的结果好处,并以可组合的方式处理错误。总函数是指对于所有可能的参数值,始终返回声明的返回类型值的函数。如果它们抛出异常,它们的函数就不再是总函数,而且在没有明确的错误处理的情况下,非全性将通过它们的代码传递,'感染'所有调用它们的其他函数,使得这些函数也变得不全。结果就是,他们最终会得到一段更难以推理的代码,并且需要更多的工作来确保其正确性。
在使用Try
的同时抛出异常也将违背首次使用Try
的目的,无端地使消费其API的代码变得更加复杂,因为API使用者将不得不同时使用Try
进行错误处理和捕获异常。
英文:
You are not being too strict.
The whole point of using Try
as a return value is the resulting benefit of programming with total functions and having a composable way of handling errors. Total functions are functions that always return a value of the declared return type for all possible argument values. If they are throwing exceptions, their functions are not total functions anymore, and—without explicit error handling—non-totality will propagate transitively through their code, 'infecting' all other functions that call them with non-totality. As a result, they will end up with code that will be much harder to reason about and it will take more effort to make sure it is correct.
Throwing exceptions while using Try
would also defy the purpose of using Try
in the first place and it would unnecessarily complicate the code consuming their API for no obvious benefit, because the API consumers will have to do error handling both using Try
and catching exceptions.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论