Skip to content

Commit 6e9074e

Browse files
Capture unexpected future-launch errors
1 parent 668cd62 commit 6e9074e

5 files changed

+36
-4
lines changed

Diff for: DESCRIPTION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Package: future
2-
Version: 1.40.0-9002
2+
Version: 1.40.0-9003
33
Title: Unified Parallel and Distributed Processing in R for Everyone
44
Depends:
55
R (>= 3.2.0)

Diff for: NAMESPACE

+1
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ export(FutureError)
138138
export(FutureGlobals)
139139
export(FutureInterruptError)
140140
export(FutureJournalCondition)
141+
export(FutureLaunchError)
141142
export(FutureMessage)
142143
export(FutureResult)
143144
export(FutureWarning)

Diff for: NEWS.md

+10
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@
44

55
* Now `print()` for `Future` reports also on the current state of the
66
future, e.g. 'created', 'running', 'finished', and 'interrupted'.
7+
8+
## Bug Fixes
9+
10+
* In rare cases, a future backend might fails to launch a future and
11+
at the same time fail to handle such errors. That would result in
12+
hard-to-understand, obscure errors. Now these errors are detected
13+
by the **future** package and resignaled as informative errors of
14+
class `FutureLaunchError`. This also allows the future that failed
15+
to be launched to be reset and relaunched again, possible on
16+
another future backend.
717

818

919
# Version 1.40.0 [2025-04-10]

Diff for: R/backend_api-Future-class.R

+12-1
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,18 @@ run.Future <- function(future, ...) {
443443
if (debug) mdebug_push("Launching futures ...")
444444
future[["backend"]] <- backend
445445
future[["start"]] <- proc.time()[[3]]
446-
future2 <- launchFuture(backend, future = future)
446+
future2 <- tryCatch(
447+
launchFuture(backend, future = future)
448+
, FutureError = function(ex) {
449+
## Known error caught by the future backend
450+
stop(ex)
451+
}, error = function(ex) {
452+
## Unexpected error
453+
msg <- conditionMessage(ex)
454+
label <- sQuoteLabel(future[["label"]])
455+
msg <- sprintf("Caught an unexpected error of class %s when trying to launch future (%s) on backend of class %s. The reason was: %s", class(ex)[1], label, class(backend)[1], msg)
456+
stop(FutureLaunchError(msg, future = future))
457+
})
447458
if (debug) mdebug_pop("Launching futures ... done")
448459
if (debug) mdebug("Future launched: ", commaq(class(future2)))
449460
stop_if_not(inherits(future2, "Future"))

Diff for: R/protected_api-FutureCondition-class.R

+12-2
Original file line numberDiff line numberDiff line change
@@ -315,11 +315,21 @@ DeviceMisuseFutureError <- function(...) {
315315
}
316316

317317

318+
319+
#' @rdname FutureCondition
320+
#' @export
321+
FutureLaunchError <- function(..., future = NULL) {
322+
cond <- FutureError(..., future = future)
323+
class <- c("FutureLaunch", class(cond))
324+
class(cond) <- class[!duplicated(class, fromLast = TRUE)]
325+
cond
326+
}
327+
318328
#' @rdname FutureCondition
319329
#' @export
320330
FutureInterruptError <- function(..., future = NULL) {
321331
cond <- FutureError(..., future = future)
322-
class <- c("FutureInterruptError", "FutureError", class(cond))
332+
class <- c("FutureInterruptError", class(cond))
323333
class(cond) <- class[!duplicated(class, fromLast = TRUE)]
324334
cond
325335
}
@@ -329,7 +339,7 @@ FutureInterruptError <- function(..., future = NULL) {
329339
#' @export
330340
FutureDroppedError <- function(..., future = NULL) {
331341
cond <- FutureError(..., future = future)
332-
class <- c("FutureDroppedError", "FutureError", class(cond))
342+
class <- c("FutureDroppedError", class(cond))
333343
class(cond) <- class[!duplicated(class, fromLast = TRUE)]
334344
cond
335345
}

0 commit comments

Comments
 (0)