Skip to content

Commit 13a175d

Browse files
committed
Reduce amount of call stack used in hybrid_chain
Replaces `tryCatch` in `hybrid_chain` with `withCallingHandlers`. This improves Shiny on webR on Safari < 16.4 by reducing the amount of call stack used during deep nested calls to `hybrid_chain`. A `delayedAssign` is used so that if the error condition handler is invoked, the condition is handled or re-thrown in the context of `hybrid_chain`, rather than the context of the inner function deeper in the stack. The `finally` argument is reimplemented with an `on.exit()`.
1 parent b129739 commit 13a175d

File tree

1 file changed

+16
-7
lines changed

1 file changed

+16
-7
lines changed

R/utils.R

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,7 +1511,19 @@ hybrid_chain <- function(expr, ..., catch = NULL, finally = NULL,
15111511

15121512
do <- function() {
15131513
runFinally <- TRUE
1514-
tryCatch(
1514+
on.exit({ if (runFinally && !is.null(finally)) finally() })
1515+
1516+
catch_e <- NULL
1517+
delayedAssign("do_catch",
1518+
if (!is.null(catch)) {
1519+
catch(catch_e)
1520+
return()
1521+
} else {
1522+
stop(catch_e)
1523+
}
1524+
)
1525+
1526+
withCallingHandlers(
15151527
{
15161528
captureStackTraces({
15171529
result <- withVisible(force(expr))
@@ -1539,12 +1551,9 @@ hybrid_chain <- function(expr, ..., catch = NULL, finally = NULL,
15391551
})
15401552
},
15411553
error = function(e) {
1542-
if (!is.null(catch))
1543-
catch(e)
1544-
else
1545-
stop(e)
1546-
},
1547-
finally = if (runFinally && !is.null(finally)) finally()
1554+
catch_e <<- e
1555+
do_catch
1556+
}
15481557
)
15491558
}
15501559

0 commit comments

Comments
 (0)