You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何使用catch/then处理future_promise错误仍显示“Unhandled”?

future_promise错误处理后仍提示"Unhandled"且工作进程未释放的解决方法

问题复现代码

library(future)
library(promises)
plan(multicore, workers = 3)

Sys.getpid()
# [1] 1270066
nbrOfFreeWorkers()
# [1] 3
thisproc <- promises::future_promise({
  setTimeLimit(elapsed = 2, transient = TRUE)
  Sys.sleep(3)
  1L
}, seed = TRUE) %>%
  promises::then(
    function(val) {
      message("survived: ", val)
      val
    }) %>%
  catch(
    function(error) {
      message("terminated: ", substring(conditionMessage(error), 1, 16))
      NULL
    })

出现的问题

  • 已通过catch()处理错误(打印了terminated: Unexpected resul),但仍输出Unhandled promise error提示
  • 错误信息被重复报告两次
  • 执行nbrOfFreeWorkers()返回2,需手动调用resetWorkers(plan())才能恢复为3

问题原因

该问题源于future与promises包的版本兼容性:在future 1.30.0与promises 1.2.0.1的组合下,当future因超时被强制终止时,返回的结果为NULL,不符合promises预期的FutureResult类型,导致错误处理逻辑未正确标记rejectionHandled,进而触发未处理错误的二次提示;同时异常终止的工作进程未被自动回收。

解决方案

方案1:升级future包(推荐)

future 1.31.0已修复该结果类型不匹配的问题,执行以下命令升级:

install.packages("future")

升级后重新运行代码:

  • 错误处理逻辑会正常标记rejectionHandled,不再出现Unhandled promise error提示
  • 工作进程会自动释放,nbrOfFreeWorkers()返回3,无需手动重置
  • 错误仅被catch()处理一次,无重复报告

方案2:临时兼容处理(无法升级时)

若无法升级future包,需在catch()中返回符合要求的FutureResult对象,而非NULL,同时手动处理工作进程回收:

thisproc <- promises::future_promise({
  setTimeLimit(elapsed = 2, transient = TRUE)
  Sys.sleep(3)
  1L
}, seed = TRUE) %>%
  promises::then(
    function(val) {
      message("survived: ", val)
      val
    }) %>%
  catch(
    function(error) {
      message("terminated: ", substring(conditionMessage(error), 1, 16))
      # 返回标准FutureResult对象
      structure(list(result = NULL, condition = error), class = "FutureResult")
    })

# 手动回收残留的异常工作进程
if (nbrOfFreeWorkers() < plan()$workers) {
  resetWorkers(plan())
}

内容的提问来源于stack exchange,提问作者r2evans

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 16:46:08