mirror of
https://github.com/rstudio/shiny.git
synced 2026-01-14 09:28:02 -05:00
fix: Wrap extended task invocation in promise_resolve() (#4225)
* fix: Wrap extended task invocation in `promise_resolve()` * refactor: cleanup error handling and promise chain * chore: add news entry
This commit is contained in:
committed by
GitHub
parent
6df0bb9423
commit
eac0eea886
4
NEWS.md
4
NEWS.md
@@ -23,6 +23,8 @@
|
||||
|
||||
* Shiny's Typescript assets are now compiled to ES2021 instead of ES5. (#4066)
|
||||
|
||||
* `ExtendedTask` now catches synchronous values and errors and returns them via `$result()`. Previously, the extended task function was required to always return a promise. This change makes it easier to use `ExtendedTask` with a function that may return early or do some synchronous work before returning a promise. (#4225)
|
||||
|
||||
## Bug fixes
|
||||
|
||||
* Fixed a bug with modals where calling `removeModal()` too quickly after `showModal()` would fail to remove the modal if the remove modal message was received while the modal was in the process of being revealed. (#4173)
|
||||
@@ -31,6 +33,8 @@
|
||||
|
||||
* Updated the JavaScript used when inserting a tab to avoid rendering dynamic UI elements twice when adding the new tab via `insertTab()` or `bslib::nav_insert()`. (#4179)
|
||||
|
||||
* Fixed an issue with `ExtendedTask` where synchronous errors would cause an error that would stop the current session. (#4225)
|
||||
|
||||
# shiny 1.10.0
|
||||
|
||||
## New features and improvements
|
||||
|
||||
@@ -130,14 +130,15 @@ ExtendedTask <- R6Class("ExtendedTask", portable = TRUE, cloneable = FALSE,
|
||||
#' arguments.
|
||||
invoke = function(...) {
|
||||
args <- rlang::dots_list(..., .ignore_empty = "none")
|
||||
call <- rlang::caller_call(n = 0)
|
||||
|
||||
if (
|
||||
isolate(private$rv_status()) == "running" ||
|
||||
private$invocation_queue$size() > 0
|
||||
) {
|
||||
private$invocation_queue$add(args)
|
||||
private$invocation_queue$add(list(args = args, call = call))
|
||||
} else {
|
||||
private$do_invoke(args)
|
||||
private$do_invoke(args, call = call)
|
||||
}
|
||||
invisible(NULL)
|
||||
},
|
||||
@@ -204,44 +205,41 @@ ExtendedTask <- R6Class("ExtendedTask", portable = TRUE, cloneable = FALSE,
|
||||
rv_error = NULL,
|
||||
invocation_queue = NULL,
|
||||
|
||||
do_invoke = function(args) {
|
||||
do_invoke = function(args, call = NULL) {
|
||||
private$rv_status("running")
|
||||
private$rv_value(NULL)
|
||||
private$rv_error(NULL)
|
||||
|
||||
p <- NULL
|
||||
tryCatch({
|
||||
maskReactiveContext({
|
||||
# TODO: Bounce the do.call off of a promise_resolve(), so that the
|
||||
# call to invoke() always returns immediately?
|
||||
result <- do.call(private$func, args)
|
||||
p <- promises::as.promise(result)
|
||||
})
|
||||
}, error = function(e) {
|
||||
private$on_error(e)
|
||||
})
|
||||
p <- promises::promise_resolve(
|
||||
maskReactiveContext(do.call(private$func, args))
|
||||
)
|
||||
|
||||
promises::finally(
|
||||
promises::then(p,
|
||||
onFulfilled = function(value, .visible) {
|
||||
private$on_success(list(value=value, visible=.visible))
|
||||
},
|
||||
onRejected = function(error) {
|
||||
private$on_error(error)
|
||||
}
|
||||
),
|
||||
onFinally = function() {
|
||||
if (private$invocation_queue$size() > 0) {
|
||||
private$do_invoke(private$invocation_queue$remove())
|
||||
}
|
||||
p <- promises::then(
|
||||
p,
|
||||
onFulfilled = function(value, .visible) {
|
||||
private$on_success(list(value = value, visible = .visible))
|
||||
},
|
||||
onRejected = function(error) {
|
||||
private$on_error(error, call = call)
|
||||
}
|
||||
)
|
||||
|
||||
promises::finally(p, onFinally = function() {
|
||||
if (private$invocation_queue$size() > 0) {
|
||||
next_call <- private$invocation_queue$remove()
|
||||
private$do_invoke(next_call$args, next_call$call)
|
||||
}
|
||||
})
|
||||
|
||||
invisible(NULL)
|
||||
},
|
||||
|
||||
on_error = function(err) {
|
||||
on_error = function(err, call = NULL) {
|
||||
cli::cli_warn(
|
||||
"ERROR: An error occurred when invoking the ExtendedTask.",
|
||||
parent = err,
|
||||
call = call
|
||||
)
|
||||
private$rv_status("error")
|
||||
private$rv_error(err)
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user