如何正确处理 Optional.orElseGet() 的异常

How to handle exceptions with Optional.orElseGet() properly

我想调用一个以字符串作为参数和 returns 一些状态的端点,但问题是,有时我需要再次调用此端点,如果第一次调用是初始值参数失败。

即服务AreturnId="123"调用服务B,但是服务Breturns404,然后我想用[=17再次调用服务B =]. (这样保证我有地位。)

我想知道我是否可以使用 Optionals 而不是使用很多 try/catch 和 if/else 块来做到这一点。

这是我的资料:

private String fetchStatus(Order order) {
    var status = Optional.ofNullable(order.getReturnId())
        .map(returnId -> getStatus(order.returnId))
        .orElseGet(() -> getStatus(order.getId()));

    log.info("Current status: {}", status);
    return status;
}

private String getStatus(String id) {
    try {
        return externalService.getOrderStatus(id);
    } catch (Exception e) {
        throw new IllegalStateException("Failed to fetch status for order.", e);
    }
}

上面代码的问题在于,如果服务 B (externalService) returns 未找到 404,我的代码从不尝试调用替代项 (orElseGet)。

我理解错了什么?

Return null 而不是抛出异常,这样你的 Optional.ofNullabe 就会启动。

private String getStatus(String id) {
    try {
        return externalService.getOrderStatus(id);
    } catch (Exception e) {
        //log something so you knwo what happened
        return null;
    }

如果这是一般的好方法,那就是另一回事了。

另一种方法是让 externalService#getOrderStatus(...) return 一个 Optional<String> 而不是抛出异常,这会使 #fetchStatus(...) 看起来像下面这样:

private String fetchStatus(Order order) {
    var status = Optional.ofNullable(order.getReturnId())
        .flatMap(externalService::getOrderStatus)
        .or(() -> externalService.getOrderStatus(order.getId()))
        .orElseThrow(() -> new IllegalStateException("should not happen according to your question"));
    log.info("Current status: {}", status);
    return status;
}