Experiment with error message (#3007)

This commit is contained in:
Hadley Wickham
2020-12-04 14:20:30 -06:00
committed by GitHub
parent 39a23af138
commit f169792e59
5 changed files with 55 additions and 30 deletions

View File

@@ -76,8 +76,10 @@ Progress <- R6Class(
min = 0, max = 1,
style = getShinyOption("progress.style", default = "notification"))
{
if (is.null(session))
rlang::abort("Can only use Progress$new() inside a Shiny app")
if (is.null(session$progressStack))
stop("'session' is not a ShinySession object.")
rlang::abort("`session` is not a ShinySession object.")
private$session <- session
private$id <- createUniqueId(8)

View File

@@ -65,7 +65,7 @@ Context <- R6Class(
that have been registered with onInvalidate()."
if (!identical(.pid, processId())) {
stop("Reactive context was created in one process and invalidated from another")
rlang::abort("Reactive context was created in one process and invalidated from another.")
}
if (.invalidated)
@@ -87,7 +87,7 @@ Context <- R6Class(
immediately."
if (!identical(.pid, processId())) {
stop("Reactive context was created in one process and accessed from another")
rlang::abort("Reactive context was created in one process and accessed from another.")
}
if (.invalidated)
@@ -140,9 +140,13 @@ ReactiveEnvironment <- R6Class(
if (isTRUE(getOption('shiny.suppressMissingContextError'))) {
return(getDummyContext())
} else {
stop('Operation not allowed without an active reactive context. ',
'(You tried to do something that can only be done from inside a ',
'reactive expression or observer.)')
rlang::abort(c(
'Operation not allowed without an active reactive context.',
paste0(
'You tried to do something that can only be done from inside a ',
'reactive consumer.'
)
))
}
}
return(.currentContext)

View File

@@ -105,9 +105,7 @@ ReactiveVal <- R6Class(
invisible(TRUE)
},
freeze = function(session = getDefaultReactiveDomain()) {
if (is.null(session)) {
stop("Can't freeze a reactiveVal without a reactive domain")
}
checkReactiveDomain(session)
rLog$freezeReactiveVal(private$reactId, session)
session$onFlushed(function() {
self$thaw(session)
@@ -238,17 +236,23 @@ freezeReactiveVal <- function(x) {
}
domain <- getDefaultReactiveDomain()
if (is.null(domain)) {
stop("freezeReactiveVal() must be called when a default reactive domain is active.")
}
checkReactiveDomain(domain)
if (!inherits(x, "reactiveVal")) {
stop("x must be a reactiveVal object")
rlang::abort("`x` must be a reactiveVal.")
}
attr(x, ".impl", exact = TRUE)$freeze(domain)
invisible()
}
checkReactiveDomain <- function(x) {
if (is.null(x)) {
rlang::abort("Can't freeze reactive values without a reactive domain.")
}
}
#' @export
format.reactiveVal <- function(x, ...) {
attr(x, ".impl", exact = TRUE)$format(...)
@@ -566,7 +570,7 @@ ReactiveValues <- R6Class(
reactiveValues <- function(...) {
args <- list(...)
if ((length(args) > 0) && (is.null(names(args)) || any(names(args) == "")))
stop("All arguments passed to reactiveValues() must be named.")
rlang::abort("All arguments passed to reactiveValues() must be named.")
values <- .createReactiveValues(ReactiveValues$new())
@@ -577,7 +581,7 @@ reactiveValues <- function(...) {
checkName <- function(x) {
if (!is.character(x) || length(x) != 1) {
stop("Must use single string to index into reactivevalues")
rlang::abort("Must use single string to index into reactivevalues.")
}
}
@@ -619,6 +623,14 @@ is.reactivevalues <- function(x) inherits(x, 'reactivevalues')
#' @export
`$.reactivevalues` <- function(x, name) {
checkName(name)
if (!hasCurrentContext()) {
rlang::abort(c(
paste0("Can't access reactive value '", name, "' outside of reactive consumer."),
i = "Do you need to wrap inside reactive() or observer()?"
))
}
.subset2(x, 'impl')$get(.subset2(x, 'ns')(name))
}
@@ -628,7 +640,7 @@ is.reactivevalues <- function(x) inherits(x, 'reactivevalues')
#' @export
`$<-.reactivevalues` <- function(x, name, value) {
if (.subset2(x, 'readonly')) {
stop("Attempted to assign value to a read-only reactivevalues object")
rlang::abort(paste0("Can't modify read-only reactive value '", name, "'"))
}
checkName(name)
.subset2(x, 'impl')$set(.subset2(x, 'ns')(name), value)
@@ -640,12 +652,12 @@ is.reactivevalues <- function(x) inherits(x, 'reactivevalues')
#' @export
`[.reactivevalues` <- function(values, name) {
stop("Single-bracket indexing of reactivevalues object is not allowed.")
rlang::abort("Can't index reactivevalues with `[`.")
}
#' @export
`[<-.reactivevalues` <- function(values, name, value) {
stop("Single-bracket indexing of reactivevalues object is not allowed.")
rlang::abort("Can't index reactivevalues with `[`.")
}
#' @export
@@ -661,7 +673,7 @@ names.reactivevalues <- function(x) {
#' @export
`names<-.reactivevalues` <- function(x, value) {
stop("Can't assign names to reactivevalues object")
rlang::abort("Can't assign names to reactivevalues.")
}
#' @export
@@ -785,9 +797,7 @@ str.reactivevalues <- function(object, indent.str = " ", ...) {
#' @export
freezeReactiveValue <- function(x, name) {
domain <- getDefaultReactiveDomain()
if (is.null(domain)) {
stop("freezeReactiveValue() must be called when a default reactive domain is active.")
}
checkReactiveDomain(domain)
domain$freezeValue(x, name)
invisible()
@@ -819,9 +829,10 @@ Observable <- R6Class(
domain = getDefaultReactiveDomain(),
..stacktraceon = TRUE) {
if (length(formals(func)) > 0)
stop("Can't make a reactive expression from a function that takes one ",
"or more parameters; only functions without parameters can be ",
"reactive.")
rlang::abort(c(
"Can't make a reactive expression from a function that takes arguments.",
"Only functions without parameters can become reactive expressions."
))
# This is to make sure that the function labels that show in the profiler
# and in stack traces doesn't contain whitespace. See
@@ -1061,7 +1072,7 @@ execCount <- function(x) {
else if (inherits(x, 'Observer'))
return(x$.execCount)
else
stop('Unexpected argument to execCount')
rlang::abort("Unexpected argument to execCount().")
}
# Internal utility functions for extracting things out of reactives.
@@ -1101,8 +1112,10 @@ Observer <- R6Class(
domain = getDefaultReactiveDomain(),
autoDestroy = TRUE, ..stacktraceon = TRUE) {
if (length(formals(observerFunc)) > 0)
stop("Can't make an observer from a function that takes parameters; ",
"only functions without parameters can be reactive.")
rlang::abort(c(
"Can't make an observer from a function that takes arguments.",
"Only functions without arguments can become observers."
))
if (grepl("\\s", label, perl = TRUE)) {
funcLabel <- "<observer>"
} else {

View File

@@ -1187,7 +1187,10 @@ ShinySession <- R6Class(
private$.outputOptions[[name]] <- list()
}
else {
stop(paste("Unexpected", class(func), "output for", name))
rlang::abort(c(
paste0("Unexpected ", class(func)[[1]], " object for output$", name),
i = "Did you forget to use a render function?"
))
}
},
getOutput = function(name) {

View File

@@ -1779,7 +1779,10 @@ getSliderType <- function(min, max, value) {
else "number"
}))
if (length(type) > 1) {
stop("Type mismatch for `min`, `max`, and `value`. Each must be Date, POSIXt, or number.")
rlang::abort(c(
"Type mismatch for `min`, `max`, and `value`.",
"All values must either be numeric, Date, or POSIXt."
))
}
type[[1]]
}