Stack trace manipulation functions — stacktrace

v1.9.0|Source: R/conditions.R

Description

Advanced (borderline internal) functions for capturing, printing, and manipulating stack traces.

captureStackTraces(expr)

withLogErrors(
  expr,
  full = get_devmode_option("shiny.fullstacktrace", FALSE),
  offset = getOption("shiny.stacktraceoffset", TRUE)
)

printError(
  cond,
  full = get_devmode_option("shiny.fullstacktrace", FALSE),
  offset = getOption("shiny.stacktraceoffset", TRUE)
)

printStackTrace(
  cond,
  full = get_devmode_option("shiny.fullstacktrace", FALSE),
  offset = getOption("shiny.stacktraceoffset", TRUE)
)

conditionStackTrace(cond)

conditionStackTrace(cond) <- value

..stacktraceon..(expr)

..stacktraceoff..(expr)

Arguments

expr

The expression to wrap.

full

If TRUE, then every element of sys.calls() will be included in the stack trace. By default (FALSE), calls that Shiny deems uninteresting will be hidden.

offset

If TRUE (the default), srcrefs will be reassigned from the calls they originated from, to the destinations of those calls. If you're used to stack traces from other languages, this feels more intuitive, as the definition of the function indicated in the call and the location specified by the srcref match up. If FALSE, srcrefs will be left alone (traditional R treatment where the srcref is of the callsite).

cond

A condition that may have previously been annotated by captureStackTraces (or withLogErrors).

value

The stack trace value to assign to the condition.

Value

printError and printStackTrace return invisible(). The other functions pass through the results of expr.

Details

captureStackTraces runs the given expr and if any uncaught errors occur, annotates them with stack trace info for use by printError and printStackTrace. It is not necessary to use captureStackTraces around the same expression as withLogErrors, as the latter includes a call to the former. Note that if expr contains calls (either directly or indirectly) to try, or tryCatch with an error handler, stack traces therein cannot be captured unless another captureStackTraces call is inserted in the interior of the try or tryCatch. This is because these calls catch the error and prevent it from traveling up to the condition handler installed by captureStackTraces.

withLogErrors captures stack traces and logs errors that occur in expr, but does allow errors to propagate beyond this point (i.e. it doesn't catch the error). The same caveats that apply to captureStackTraces with regard to try/tryCatch apply to withLogErrors.

printError prints the error and stack trace (if any) using warning(immediate.=TRUE). printStackTrace prints the stack trace only.

conditionStackTrace and conditionStackTrace<- are accessor functions for getting/setting stack traces on conditions.

The two functions ..stacktraceon.. and ..stacktraceoff.. have no runtime behavior during normal execution; they exist only to create artifacts on the stack trace (sys.call()) that instruct the stack trace pretty printer what parts of the stack trace are interesting or not. The initial state is 1 and we walk from the outermost call inwards. Each ..stacktraceoff.. decrements the state by one, and each ..stacktraceon.. increments the state by one. Any stack trace frame whose value is less than 1 is hidden, and finally, the ..stacktraceon.. and ..stacktraceoff.. calls themselves are hidden too.

Examples

# Keeps tryCatch and withVisible related calls off the
# pretty-printed stack trace

visibleFunction1 <- function() {
  stop("Kaboom!")
}

visibleFunction2 <- function() {
  visibleFunction1()
}

hiddenFunction <- function(expr) {
  expr
}

# An example without ..stacktraceon/off.. manipulation.
# The outer "try" is just to prevent example() from stopping.
try({
  # The withLogErrors call ensures that stack traces are captured
  # and that errors that bubble up are logged using warning().
  withLogErrors({
    # tryCatch and withVisible are just here to add some noise to
    # the stack trace.
    tryCatch(
      withVisible({
        hiddenFunction(visibleFunction2())
      })
    )
  })
})

# Now the same example, but with ..stacktraceon/off.. to hide some
# of the less-interesting bits (tryCatch and withVisible).
..stacktraceoff..({
  try({
    withLogErrors({
      tryCatch(
        withVisible(
          hiddenFunction(
            ..stacktraceon..(visibleFunction2())
          )
        )
      )
    })
  })
})