如何返回发生的第一个异常?

时间:2017-11-16 20:31:57

标签: java java-8 functional-programming optional vavr

有一个名为validate的方法,作为输入接受OptionPredicate的实例 - 两个参数(是的,我知道Option应该作为参数传递但是这是简化的现实场景。现在,如果Option为空,我需要抛出NotFoundException。如果它的值不匹配Predicate,则应该{ ForbiddenException失败。如果它有值且与谓词匹配则没有任何反应。

所以这将是:

                Option, Predicate
                     /\
          isEmpty() /  \ isDefined()  
                   /    \
            throw NFE    matches(Predicate)
                        / \
                    no /   \ yes 
                      /     \
                throw FE     end

我有一些解决方案,但希望潜在的回答者能够清醒地回答这个问题;)如果两个测试失败,我的问题就是获得第一个异常。如果我可以期待任何事情,我期待一个优雅的解决方案;)允许所有vavr生成(EitherValidationTry ..)

其中一个想法是使用双Option

Option
  .of(o.getOrElseThrow(NotFoundException::new))
  .filter(p)
  .getOrElseThrow(ForbiddenException::new);

但这看起来有点尴尬。

可以找到

Here示例项目。

3 个答案:

答案 0 :(得分:4)

在我看来,最好的选择是创建可读代码,在这种情况下意味着使用两个div.shipping语句:

if

对于将来需要维护此代码的人来说,简单,可读和直接。

尽管如此,你仍然希望以某种功能 ish 风格来实现它:

if (!o.isPresent()) throw new NotFoundException();
if (!p.test(o.get())) throw new ForbiddenException();

使用Java 9:

o.orElseThrow(NotFoundException::new);
o.filter(p).orElseThrow(ForbiddenException::new);

答案 1 :(得分:2)

这将是Optional的解决方案(没有时间检查vavr但应该足够接近)

public static <T> void validate( Optional<T> optional, Predicate<T> pred ) throws NotFoundException, ForbiddenException {
    if ( !pred.test( optional.orElseThrow( NotFoundException::new ) ) )
        throw new ForbiddenException();
}

不幸的是,不知道抛出ForbiddenException的更漂亮的方法。

如果您需要全功能解决方案,则需要Optional

Optional.of( 
    pred.test( 
       option.orElseThrow( NotFoundException::new ) 
    ) 
).filter( b -> b ).orElseThrow( ForbiddenException::new );

由于我们仅在Predicate检查后检查option,因此会以正确的顺序抛出异常。

答案 2 :(得分:0)

final CheckedFunction2<Option<T>, Predicate<T>, T> 
    f = (option, predicate) ->
    Try.of(() -> option.getOrElseThrow(NotFoundException::new))
       .filter(predicate, ForbiddenException::new)
       .get();