所以我有一个返回 Vavr Try
的方法:
public Try<Result> request() {...}
request
来 self 无法修改的来源。目前,我对 request
的结果进行了平面映射。并取决于 Result
有错误返回 Try
出现异常或成功,数据来自 Result
:
public Try<Data> fetchData() {
return request().flatMap(result -> {
if (result.hasError()) {
return Try.failure(new FailedRequestException());
} else {
return Try.success(result.data());
}
});
}
我想要的是在一些地方fetchData
如果 Try
首先对数据进行处理表示成功,如果失败,则记录错误(如果错误为 FailedRequestException
) ,否则,做一些异常(exception)的事情,如下所示:
fetchData().andThen(data -> ...).onFailure(ex -> {
if (ex instanceOf FailedRequestException) {
log.error("Could not fetch data: " + ex.getMessage());
} else {
// Do something with the exception
...
}
});
我对这种方法的问题是 fetchData
返回 Try
所以调用者无法知道 FailedRequestException
是可能失败的一部分。我可以让 fetchData
返回 Try<Either<FailedRequestException, Data>>
但这感觉也不对劲。有没有办法以更优雅的方式完成上述操作?我还尝试使用 Match
和Case
但是Case
预计 Function
作为处理程序而不是 Consumer
.
最佳答案
总结一下:您实际上有 3 种情况(成功、因 FailedRequestException 失败、任何其他失败)。这听起来像是模式匹配的工作!让我们使代码与业务需求一样可见和富有表现力:)
Match(fetchData()).of(
Case($Success($()), data -> doStuff(data)),
Case($Failure($(instanceOf(FailedRequestException.class))), fre -> logFreAndReturnValue(fre)),
Case($Failure($()), e -> doSomethingWithOtherException(e))
);
FWIW,您可以重写您的 fetchData
实现,如下所示:
Try(request())
.mapFailure(Case($(), ignored -> new FailedRequestException()))
.map(Result::data);
根据经验,当上下文(成功或失败)可能发生变化时,请尝试坚持使用 flatMap
。在您当前的 fetchData 实现中,成功仍然是成功,失败仍然是失败,因此它是输入和输出之间的映射,因此使用 map
函数族。
干杯!
关于java - 如何使用 vavr 仅记录特定异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58499653/