-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
stacktrace.Rd
157 lines (135 loc) · 4.98 KB
/
stacktrace.Rd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/conditions.R
\name{stacktrace}
\alias{stacktrace}
\alias{captureStackTraces}
\alias{withLogErrors}
\alias{printError}
\alias{printStackTrace}
\alias{conditionStackTrace}
\alias{conditionStackTrace<-}
\alias{..stacktraceon..}
\alias{..stacktraceoff..}
\title{Stack trace manipulation functions}
\usage{
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{
\item{expr}{The expression to wrap.}
\item{full}{If \code{TRUE}, then every element of \code{sys.calls()} will be
included in the stack trace. By default (\code{FALSE}), calls that Shiny
deems uninteresting will be hidden.}
\item{offset}{If \code{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 \code{FALSE}, srcrefs will be
left alone (traditional R treatment where the srcref is of the callsite).}
\item{cond}{A condition that may have previously been annotated by
\code{captureStackTraces} (or \code{withLogErrors}).}
\item{value}{The stack trace value to assign to the condition.}
}
\value{
\code{printError} and \code{printStackTrace} return
\code{invisible()}. The other functions pass through the results of
\code{expr}.
}
\description{
Advanced (borderline internal) functions for capturing, printing, and
manipulating stack traces.
}
\details{
\code{captureStackTraces} runs the given \code{expr} and if any
\emph{uncaught} errors occur, annotates them with stack trace info for use
by \code{printError} and \code{printStackTrace}. It is not necessary to use
\code{captureStackTraces} around the same expression as
\code{withLogErrors}, as the latter includes a call to the former. Note
that if \code{expr} contains calls (either directly or indirectly) to
\code{try}, or \code{tryCatch} with an error handler, stack traces therein
cannot be captured unless another \code{captureStackTraces} call is
inserted in the interior of the \code{try} or \code{tryCatch}. This is
because these calls catch the error and prevent it from traveling up to the
condition handler installed by \code{captureStackTraces}.
\code{withLogErrors} captures stack traces and logs errors that
occur in \code{expr}, but does allow errors to propagate beyond this point
(i.e. it doesn't catch the error). The same caveats that apply to
\code{captureStackTraces} with regard to \code{try}/\code{tryCatch} apply
to \code{withLogErrors}.
\code{printError} prints the error and stack trace (if any) using
\code{warning(immediate.=TRUE)}. \code{printStackTrace} prints the stack
trace only.
\code{conditionStackTrace} and \verb{conditionStackTrace<-} are
accessor functions for getting/setting stack traces on conditions.
The two functions \code{..stacktraceon..} and
\code{..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())
)
)
)
})
})
})
}
\keyword{internal}