diff --git a/NEWS.md b/NEWS.md index 407d8316..d34af1a7 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,6 +4,7 @@ * Added support for graphic devices provided by ragg and svglite (@thomasp85 #964) * `parse_rds()`, `parse_feather()`, and `parse_parquet()` no longer writes data to disk during parsing (@thomasp85, #942) +* Returning error messages are now turned off by default rather than being turned on if running interactively and turned off if not (@thomasp85, #962) # plumber 1.2.2 diff --git a/R/plumber.R b/R/plumber.R index 0cad0ec6..eed20aef 100644 --- a/R/plumber.R +++ b/R/plumber.R @@ -143,7 +143,7 @@ Plumber <- R6Class( #' Mac OS X, port numbers smaller than 1025 require root privileges. #' #' This value does not need to be explicitly assigned. To explicitly set it, see [options_plumber()]. - #' @param debug If `TRUE`, it will provide more insight into your API errors. Using this value will only last for the duration of the run. If a `$setDebug()` has not been called, `debug` will default to `interactive()` at `$run()` time. See `$setDebug()` for more details. + #' @param debug If `TRUE`, it will provide more insight into your API errors. Using this value will only last for the duration of the run. If a `$setDebug()` has not been called, `debug` will default to `FALSE` at `$run()` time. See `$setDebug()` for more details. #' @param swagger Deprecated. Please use `docs` instead. See `$setDocs(docs)` or `$setApiSpec()` for more customization. #' @param swaggerCallback An optional single-argument function that is #' called back with the URL to an OpenAPI user interface when one becomes @@ -223,17 +223,16 @@ Plumber <- R6Class( ) ) - # Delay the setting of debug as long as possible. - # The router could be made in an interactive setting and used in background process. - # Do not determine if interactive until run time + # Temporarily set the debug value prev_debug <- private$debug on.exit({ private$debug <- prev_debug }, add = TRUE) - # Fix the debug value while running. + # Determine if the user should be informed about default behavior + inform_debug <- is.null(prev_debug) && rlang::is_missing(debug) + + # Set debug value, defaulting to already set value (which returns FALSE if not set) self$setDebug( - # Order: Run method param, internally set value, is interactive() - # `$getDebug()` is dynamic given `setDebug()` has never been called. rlang::maybe_missing(debug, self$getDebug()) ) @@ -267,6 +266,14 @@ Plumber <- R6Class( on.exit(unmount_docs(self, docs_info), add = TRUE) } + if (!isTRUE(quiet) && inform_debug && rlang::is_interactive()) { + rlang::inform( + "Error reporting has been turned off by default. See `pr_set_debug()` for more details.\nTo disable this message, set a debug value.", + .frequency="once", + .frequency_id="pr_set_debug_message" + ) + } + on.exit(private$runHooks("exit"), add = TRUE) httpuv::runServer(host, port, self) @@ -963,15 +970,15 @@ Plumber <- R6Class( #' #' See also: `$getDebug()` and [pr_set_debug()] #' @param debug `TRUE` provides more insight into your API errors. - setDebug = function(debug = interactive()) { + setDebug = function(debug = FALSE) { stopifnot(length(debug) == 1) private$debug <- isTRUE(debug) }, - #' @description Retrieve the `debug` value. If it has never been set, the result of `interactive()` will be used. + #' @description Retrieve the `debug` value. If it has never been set, it will return `FALSE`. #' #' See also: `$getDebug()` and [pr_set_debug()] getDebug = function() { - private$debug %||% default_debug() + private$debug %||% FALSE }, #' @description Add a filter to plumber router #' @@ -1333,13 +1340,6 @@ upgrade_docs_parameter <- function(docs, ...) { ) } - - -default_debug <- function() { - interactive() -} - - urlHost <- function(scheme = "http", host, port, path = "", changeHostLocation = FALSE) { if (isTRUE(changeHostLocation)) { # upgrade callback location to be localhost and not catch-all addresses diff --git a/R/pr_set.R b/R/pr_set.R index a62c8158..24fc5004 100644 --- a/R/pr_set.R +++ b/R/pr_set.R @@ -97,8 +97,8 @@ pr_set_error <- function(pr, fun) { #' Set debug value to include error messages of routes cause an error #' -#' To hide any error messages in production, set the debug value to `FALSE`. -#' The `debug` value is enabled by default for [interactive()] sessions. +#' By default, error messages from your plumber routes are hidden, but can be +#' turned on by setting the debug value to `TRUE` using this setter. #' #' @template param_pr #' @param debug `TRUE` provides more insight into your API errors. @@ -118,7 +118,15 @@ pr_set_error <- function(pr, fun) { #' pr_get("/boom", function() stop("boom")) %>% #' pr_run() #' } -pr_set_debug <- function(pr, debug = interactive()) { +#' +#' # Setting within a plumber file +#' #* @plumber +#' function(pr) { +#' pr %>% +#' pr_set_debug(TRUE) +#' } +#' +pr_set_debug <- function(pr, debug = FALSE) { validate_pr(pr) pr$setDebug(debug = debug) pr diff --git a/man/Plumber.Rd b/man/Plumber.Rd index 5090da29..fea92e6d 100644 --- a/man/Plumber.Rd +++ b/man/Plumber.Rd @@ -242,7 +242,7 @@ This value does not need to be explicitly assigned. To explicitly set it, see \c \item{\code{swagger}}{Deprecated. Please use \code{docs} instead. See \verb{$setDocs(docs)} or \verb{$setApiSpec()} for more customization.} -\item{\code{debug}}{If \code{TRUE}, it will provide more insight into your API errors. Using this value will only last for the duration of the run. If a \verb{$setDebug()} has not been called, \code{debug} will default to \code{interactive()} at \verb{$run()} time. See \verb{$setDebug()} for more details.} +\item{\code{debug}}{If \code{TRUE}, it will provide more insight into your API errors. Using this value will only last for the duration of the run. If a \verb{$setDebug()} has not been called, \code{debug} will default to \code{FALSE} at \verb{$run()} time. See \verb{$setDebug()} for more details.} \item{\code{swaggerCallback}}{An optional single-argument function that is called back with the URL to an OpenAPI user interface when one becomes @@ -788,7 +788,7 @@ Set debug value to include error messages. See also: \verb{$getDebug()} and \code{\link[=pr_set_debug]{pr_set_debug()}} \subsection{Usage}{ -\if{html}{\out{
}}\preformatted{Plumber$setDebug(debug = interactive())}\if{html}{\out{
}} +\if{html}{\out{
}}\preformatted{Plumber$setDebug(debug = FALSE)}\if{html}{\out{
}} } \subsection{Arguments}{ @@ -803,7 +803,7 @@ See also: \verb{$getDebug()} and \code{\link[=pr_set_debug]{pr_set_debug()}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Plumber-getDebug}{}}} \subsection{Method \code{getDebug()}}{ -Retrieve the \code{debug} value. If it has never been set, the result of \code{interactive()} will be used. +Retrieve the \code{debug} value. If it has never been set, it will return \code{FALSE}. See also: \verb{$getDebug()} and \code{\link[=pr_set_debug]{pr_set_debug()}} \subsection{Usage}{ diff --git a/man/pr_set_debug.Rd b/man/pr_set_debug.Rd index cfeb9b3d..66d73da2 100644 --- a/man/pr_set_debug.Rd +++ b/man/pr_set_debug.Rd @@ -4,7 +4,7 @@ \alias{pr_set_debug} \title{Set debug value to include error messages of routes cause an error} \usage{ -pr_set_debug(pr, debug = interactive()) +pr_set_debug(pr, debug = FALSE) } \arguments{ \item{pr}{A Plumber API. Note: The supplied Plumber API object will also be updated in place as well as returned by the function.} @@ -15,8 +15,8 @@ pr_set_debug(pr, debug = interactive()) The Plumber router with the new debug setting. } \description{ -To hide any error messages in production, set the debug value to \code{FALSE}. -The \code{debug} value is enabled by default for \code{\link[=interactive]{interactive()}} sessions. +By default, error messages from your plumber routes are hidden, but can be +turned on by setting the debug value to \code{TRUE} using this setter. } \examples{ \dontrun{ @@ -32,4 +32,12 @@ pr() \%>\% pr_get("/boom", function() stop("boom")) \%>\% pr_run() } + +# Setting within a plumber file +#* @plumber +function(pr) { + pr \%>\% + pr_set_debug(TRUE) +} + } diff --git a/tests/testthat/test-plumber-run.R b/tests/testthat/test-plumber-run.R index fe20210a..12d1eeb8 100644 --- a/tests/testthat/test-plumber-run.R +++ b/tests/testthat/test-plumber-run.R @@ -93,41 +93,3 @@ test_that("`swaggerCallback` can be set by option after the pr is created", { mockery::expect_called(m, 1) }) - - -### Test does not work as expected with R6 objects. -test_that("`debug` is not set until runtime", { - skip_if_not_installed("mockery", "0.4.2") - - m <- mockery::mock(TRUE, cycle = TRUE) - local_mocked_bindings(default_debug = m) - - root <- pr() - root$getDebug() - mockery::expect_called(m, 1) - - with_interrupt({ - root %>% pr_run(quiet = TRUE) - }) - # increase by 1 - mockery::expect_called(m, 2) - - # listen to set value - with_interrupt({ - root %>% - pr_set_debug(TRUE) %>% - pr_run(quiet = TRUE) - }) - # not updated. stay at 2 - mockery::expect_called(m, 2) - - # listen to run value - with_interrupt({ - root %>% - pr_run(debug = FALSE, quiet = TRUE) - }) - # not updated. stay at 2 - mockery::expect_called(m, 2) - - # TODO test that run(debug=) has preference over pr_set_debug() -})