Micronaut RxHttpClient响应处理doOnError失效及布尔结果获取问题
问题1:当前获取布尔类型上传结果的调用方式是否正确?
不正确,核心问题有两个:
- 在RxJava非阻塞的操作符上下文中使用
blockingFirst()这类阻塞API,破坏了响应式流的非阻塞约定,不仅会造成调度器线程的无效等待,还会在等待过程中线程被中断时直接抛出未捕获的检查异常,也就是你栈追踪里的InterruptedException。 doOnError只是异常的副作用回调,仅用于打印日志这类侧操作,不会捕获并消化异常,上传过程中抛出的异常会继续向下游传播,你没有对应的异常处理操作符接收,就会触发RxJava的全局异常兜底,抛出UndeliverableException。
问题2:这类错误应该如何正确处理?
你需要遵循响应式异步嵌套的处理规范,用flatMap打平嵌套的异步流,同时用onErrorReturn这类错误处理操作符捕获异常并返回默认结果,避免异常向外传播。
修改后的代码示例:
return files .filter(file -> file.getLocalFile() != null) .parallel(transferParallelism) .runOn(Schedulers.io()) // 异步嵌套场景使用flatMap打平Flowable,替代阻塞调用 .flatMap(file -> uploadService.uploadFile(file.getLocalFile()) // 上传成功时转换为带上传结果的文件对象 .map(response -> file.withUploaded( response.getBody(UploadFileResponse.class) .map(UploadFileResponse::isUploaded) .orElse(false) )) // 捕获所有上传异常,返回上传失败的结果并打印日志 .onErrorReturn(throwable -> { log.error("File {} upload failed", file.getLocalFile().getFileName(), throwable); return file.withUploaded(false); }) ) .sequential() .toList() .map(....);
修改后的逻辑优势:
- 全程无阻塞调用,充分利用RxJava的异步调度能力,不会出现线程中断导致的未捕获异常
- 所有上传阶段的异常都会被
onErrorReturn捕获并消化,不会向下游传播,自然不会触发UndeliverableException - 异常处理和日志逻辑聚合,代码可读性更高
内容的提问来源于stack exchange,提问作者Virkom
相关产品推荐
相关产品推荐

