如果在 API 调用期间部分失败,以下 java 代码的输出是什么?

What will be the output of the below java code in case of partial failure during API calls?

我有一个总共 115 个输入的列表,使用下面的代码将其分成 20 个输入的数据包大小,这意味着 xoneIndexListOfList 有 6 个元素,大小分别为 [ [20], [20], [20], [20], [20], [15] ]

final AtomicInteger counter = new AtomicInteger();
final Collection<List<XoneIndexRequest>> xoneIndexListOfList = xoneIndexRequestList.stream()
          .collect(Collectors.groupingBy(it -> counter.getAndIncrement() / xoneIndicesPacketSize))
              .values(); 

在第二步中,我将遍历此列表并将每个数据包作为输入传递给某个 REST 端点,使用以下代码。

return xoneIndexListOfList.stream()
       .map(e -> {
            return getResponseBody(creditIndicesApiClient.creditIndicesSearch7(e));
       }).collect(Collectors.toList());

从上面的代码中,我们可以看到 6 个调用将转到上面的 API(每个数据包 i.e.one),所以这里我的问题是如果有一些部分会发生什么失败?

场景: 假设数据包 1 和 2 通过,数据包 3 失败(即 API 无法 return 第三个数据包的数据)

**问题:**

  1. 在上面的场景中会进行到4和5包吗?如果是,那么假设数据包 4 和 5 也通过了,所以总共数据包 1,2,4,5 通过但 3 失败,那么上面代码的 return 输出是什么?
  2. 如果否,他们将只return编辑数据包 1 和 2 的输出,因为它已经通过并且数据包 3 的请求失败?
  3. 或者如果任何一个数据包在任何时候失败,它是否将每个数据包标记为失败,处理这个数据包列表?

编辑 - 添加完整方法

@Override
public List<XoneIndexResponse> creditIndicesSearch7(List<XoneIndexRequest> xoneIndexRequestList) {

    try {

        final AtomicInteger counter = new AtomicInteger();
        final Collection<List<XoneIndexRequest>> xoneIndexListOfList = xoneIndexRequestList.stream()
            .collect(Collectors.groupingBy(it -> counter.getAndIncrement() / xoneIndicesPacketSize))
            .values();

        return xoneIndexListOfList.stream()
            .map(e -> {
               return getResponseBody(creditIndicesApiClient.creditIndicesSearch7(e));
            }).collect(Collectors.toList());

    } catch (Exception e) {
        log.error("error while retrieving data from x-one! for Index", e);
        return emptyList();
    }
}

当发生未处理的异常时,流的处理立即停止。

所以除非你处理异常,否则你不会得到一个列表。

我们可以用下面的代码进行测试:

Stream.of(6, 0, 7)
        .map(integer -> 5/integer + integer)
        .forEach(System.out::println);

输出:

6
Exception in thread "main" java.lang.ArithmeticException: / by zero
    at com.example.demo.DemoApplication.lambda$main(DemoApplication.java:244)
    at java.util.stream.ReferencePipeline.accept(ReferencePipeline.java:193)
    at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
    at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
    at com.example.demo.DemoApplication.main(DemoApplication.java:245)

这取决于我们要做什么,但我们可以通过以下方式解决它:

Stream.of(6, 0, 7)
        .map(integer -> {
            try{
                return  Optional.of(5/integer + integer);
            }catch (ArithmeticException e){
                return Optional.empty();
            }
        })
        .filter(Optional::isPresent)
        .map(Optional::get)
        .forEach(System.out::println);

输出:

6
7

编辑:

当整个事情都包含在 try 范围内时,从流中抛出的异常将传播并在 catch 范围内被捕获。

所以在你的情况下,一个错误将被打印到日志中并且 emptyList() 将被调用。