88# '
99# ' @param message A message condition.
1010# '
11- # ' @param call The call stack that led up to the condition.
11+ # ' @param call (optional) The call stack that led up to the condition.
1212# '
13- # ' @param uuid A universally unique identifier for the future associated with
14- # ' this FutureCondition.
13+ # ' @param by (optional) A session UUID object.
1514# '
16- # ' @param future The [Future] involved.
15+ # ' @param when (optional) A [POSIXct] timestamp for when the condition was
16+ # ' created.
17+ # '
18+ # ' @param label (optional) A future label.
19+ # '
20+ # ' @param uuid (optional) A universally unique identifier for the future
21+ # ' associated with this FutureCondition.
22+ # '
23+ # ' @param future (optional) The [Future] involved.
1724# '
1825# ' @return An object of class FutureCondition which inherits from class
1926# ' \link[base:conditions]{condition} and FutureMessage, FutureWarning,
2431# '
2532# ' @export
2633# ' @keywords internal
27- FutureCondition <- function (message , call = NULL , uuid = future [[" uuid" ]], future = NULL ) {
34+ FutureCondition <- function (message , call = NULL , by = session_uuid(), when = NULL , uuid = future [[" uuid" ]], label = future [[ " label " ]], future = NULL ) {
2835 # # Support different types of input
2936 if (inherits(message , " condition" )) {
3037 cond <- message
@@ -57,46 +64,104 @@ FutureCondition <- function(message, call = NULL, uuid = future[["uuid"]], futur
5764 class <- c(" FutureCondition" , class )
5865 structure(list (message = message , call = call ),
5966 class = class [! duplicated(class , fromLast = TRUE )],
60- uuid = uuid , future = future )
67+ by = by , when = when ,
68+ label = label , uuid = uuid , future = future )
6169}
6270
6371
64- # ' @importFrom utils tail
72+ # ' @importFrom utils tail capture.output
6573# ' @export
6674print.FutureCondition <- function (x , ... ) {
6775 NextMethod()
6876
77+ lines <- character (0L )
78+
79+ by <- attr(x , " by" , exact = TRUE )
80+ when <- attr(x , " when" , exact = TRUE )
81+ if (! is.null(by )) {
82+ source <- attr(by , " source" , exact = TRUE )
83+ host <- source [[" host" ]]
84+ pid <- source [[" pid" ]]
85+ info <- c(host , sprintf(" pid %d" , pid ), as.character(when ))
86+ info <- paste(info , collapse = " ; " )
87+ lines <- c(lines , sprintf(" Occurred on: %s [%s]" , by , info ))
88+ } else if (! is.null(when )) {
89+ lines <- c(lines , sprintf(" Occurred at: %s" , when ))
90+ }
91+
6992 uuid <- attr(x , " uuid" , exact = TRUE )
70- if (is.null(uuid )) {
71- uuid <- " <NA>"
93+ label <- attr(x , " label" , exact = TRUE )
94+ label <- if (is.null(label )) {
95+ sprintf(" <%s>" , paste(c(" unnamed" , tail(uuid , 1L )), collapse = " -" ))
7296 } else {
73- uuid <- paste( uuid , collapse = " - " )
97+ label <- sQuote( label )
7498 }
75- cat(sprintf(" \n\n Future UUID: %s\n " , uuid ))
99+ uuid <- if (is.null(uuid )) " <NA>" else paste(uuid , collapse = " -" )
100+ lines <- c(lines , sprintf(" Future: %s (%s)" , uuid , label ))
76101
77- future <- attr(x , " future" , exact = TRUE )
78102
103+ future <- attr(x , " future" , exact = TRUE )
79104 if (! is.null(future )) {
80- cat(" \n\n DEBUG: BEGIN TROUBLESHOOTING HELP\n " )
81-
82- if (! is.null(future )) {
83- cat(" Future involved:\n " )
84- print(future )
85- cat(" \n " )
86- }
87-
88- cat(" DEBUG: END TROUBLESHOOTING HELP\n " )
105+ lines <- c(lines , " " , " DEBUG: BEGIN TROUBLESHOOTING HELP" )
106+ lines <- c(lines , capture.output(print(future )))
107+ lines <- c(lines , " DEBUG: END TROUBLESHOOTING HELP" )
89108 }
90109
110+ if (length(lines ) > 0 ) {
111+ lines <- c(" " , lines )
112+ writeLines(lines )
113+ }
114+
91115 invisible (x )
92116} # # print()
93117
94118
119+ # ' @export
120+ conditionMessage.FutureCondition <- function (c ) {
121+ msg <- NextMethod()
122+
123+ meta <- character ()
124+
125+ uuid <- attr(c , " uuid" , exact = TRUE )
126+ label <- attr(c , " label" , exact = TRUE )
127+ label <- if (is.null(label )) {
128+ sprintf(" <%s>" , paste(c(" unnamed" , tail(uuid , 1L )), collapse = " -" ))
129+ } else {
130+ label <- sQuote(label )
131+ }
132+ if (! is.null(uuid )) {
133+ uuid <- if (is.null(uuid )) " <NA>" else paste(uuid , collapse = " -" )
134+ meta <- c(meta , sprintf(" future %s (%s)" , label , uuid ))
135+ } else {
136+ meta <- c(meta , sprintf(" future %s" , label ))
137+ }
138+
139+ when <- attr(c , " when" , exact = TRUE )
140+ by <- attr(c , " by" , exact = TRUE )
141+ if (! is.null(by )) {
142+ source <- attr(by , " source" , exact = TRUE )
143+ host <- source [[" host" ]]
144+ pid <- source [[" pid" ]]
145+ info <- sprintf(" on %s@%s<%d>" , by , host , pid )
146+ if (! is.null(when )) info <- sprintf(" %s at %s" , info , when )
147+ meta <- c(meta , info )
148+ } else if (! is.null(when )) {
149+ meta <- c(meta , sprintf(" at %s" , when ))
150+ }
151+
152+ if (length(meta ) > 0 ) {
153+ meta <- paste(meta , collapse = " ; " )
154+ msg <- sprintf(" %s [%s]" , msg , meta )
155+ }
156+
157+ msg
158+ }
159+
95160
96161# ' @rdname FutureCondition
97162# ' @export
98- FutureMessage <- function (message , call = NULL , uuid = future [[" uuid" ]], future = NULL ) {
99- cond <- FutureCondition(message = message , call = call , uuid = uuid , future = future )
163+ FutureMessage <- function (message , call = NULL , ... , uuid = future [[" uuid" ]], future = NULL ) {
164+ cond <- FutureCondition(message = message , call = call , ... , uuid = uuid , future = future )
100165 class <- c(" FutureMessage" , " message" , class(cond ))
101166 class(cond ) <- class [! duplicated(class , fromLast = TRUE )]
102167 cond
@@ -105,8 +170,8 @@ FutureMessage <- function(message, call = NULL, uuid = future[["uuid"]], future
105170
106171# ' @rdname FutureCondition
107172# ' @export
108- FutureWarning <- function (message , call = NULL , uuid = future [[" uuid" ]], future = NULL ) {
109- cond <- FutureCondition(message = message , call = call , uuid = uuid , future = future )
173+ FutureWarning <- function (message , call = NULL , ... , uuid = future [[" uuid" ]], future = NULL ) {
174+ cond <- FutureCondition(message = message , call = call , ... , uuid = uuid , future = future )
110175 class <- c(" FutureWarning" , " warning" , class(cond ))
111176 class(cond ) <- class [! duplicated(class , fromLast = TRUE )]
112177 cond
@@ -115,8 +180,8 @@ FutureWarning <- function(message, call = NULL, uuid = future[["uuid"]], future
115180
116181# ' @rdname FutureCondition
117182# ' @export
118- FutureError <- function (message , call = NULL , uuid = future [[" uuid" ]], future = NULL ) {
119- cond <- FutureCondition(message = message , call = call , uuid = uuid , future = future )
183+ FutureError <- function (message , call = NULL , ... , uuid = future [[" uuid" ]], future = NULL ) {
184+ cond <- FutureCondition(message = message , call = call , ... , uuid = uuid , future = future )
120185 class <- c(" FutureError" , " error" , class(cond ))
121186 class(cond ) <- class [! duplicated(class , fromLast = TRUE )]
122187 cond
@@ -125,12 +190,12 @@ FutureError <- function(message, call = NULL, uuid = future[["uuid"]], future =
125190
126191# ' @rdname FutureCondition
127192# ' @export
128- RngFutureCondition <- function (message = NULL , call = NULL , uuid = future [[" uuid" ]], future = NULL ) {
193+ RngFutureCondition <- function (message = NULL , call = NULL , ... , uuid = future [[" uuid" ]], future = NULL ) {
129194 if (is.null(message )) {
130195 label <- sQuoteLabel(future )
131196 message <- sprintf(" UNRELIABLE VALUE: Future (%s) unexpectedly generated random numbers without specifying argument 'seed'. There is a risk that those random numbers are not statistically sound and the overall results might be invalid. To fix this, specify 'seed=TRUE'. This ensures that proper, parallel-safe random numbers are produced. To disable this check, use 'seed=NULL', or set option 'future.rng.onMisuse' to \" ignore\" ." , label )
132197 }
133- cond <- FutureCondition(message = message , call = call , uuid = uuid , future = future )
198+ cond <- FutureCondition(message = message , call = call , ... , uuid = uuid , future = future )
134199 class <- c(" RngFutureCondition" , class(cond ))
135200 class(cond ) <- class [! duplicated(class , fromLast = TRUE )]
136201 cond
@@ -190,13 +255,13 @@ UnexpectedFutureResultError <- function(future, hint = NULL) {
190255
191256# ' @rdname FutureCondition
192257# ' @export
193- GlobalEnvMisuseFutureCondition <- function (message = NULL , call = NULL , differences = NULL , uuid = future [[" uuid" ]], future = NULL ) {
258+ GlobalEnvMisuseFutureCondition <- function (message = NULL , call = NULL , ... , differences = NULL , uuid = future [[" uuid" ]], future = NULL ) {
194259 if (is.null(message )) {
195260 label <- sQuoteLabel(future )
196261 message <- sprintf(" %s (%s) added variables to the global environment. A future expression should never assign variables to the global environment - neither by assign() nor by <<-: [n=%d] %s" , class(future )[1 ], label , length(differences [[" added" ]]), commaq(differences [[" added" ]]))
197262 message <- sprintf(" %s. See also help(\" future.options\" , package = \" future\" )" , message )
198263 }
199- cond <- FutureCondition(message = message , call = call , uuid = uuid , future = future )
264+ cond <- FutureCondition(message = message , call = call , ... , uuid = uuid , future = future )
200265 cond [[" differences" ]] <- differences
201266 class <- c(" GlobalEnvMisuseFutureCondition" , class(cond ))
202267 class(cond ) <- class [! duplicated(class , fromLast = TRUE )]
@@ -224,7 +289,7 @@ GlobalEnvMisuseFutureError <- function(...) {
224289
225290# ' @rdname FutureCondition
226291# ' @export
227- ConnectionMisuseFutureCondition <- function (message = NULL , call = NULL , differences = NULL , uuid = future [[" uuid" ]], future = NULL ) {
292+ ConnectionMisuseFutureCondition <- function (message = NULL , call = NULL , ... , differences = NULL , uuid = future [[" uuid" ]], future = NULL ) {
228293 if (is.null(message )) {
229294 label <- sQuoteLabel(future )
230295 message <- sprintf(" %s (%s) added, removed, or modified connections. A future expression must close any opened connections and must not close connections it did not open" , class(future )[1 ], label )
@@ -247,7 +312,7 @@ ConnectionMisuseFutureCondition <- function(message = NULL, call = NULL, differe
247312 }
248313 message <- sprintf(" %s. See also help(\" future.options\" , package = \" future\" )" , message )
249314 }
250- cond <- FutureCondition(message = message , call = call , uuid = uuid , future = future )
315+ cond <- FutureCondition(message = message , call = call , ... , uuid = uuid , future = future )
251316 cond [[" differences" ]] <- differences
252317 class <- c(" ConnectionMisuseFutureCondition" , " MisuseFutureCondition" , class(cond ))
253318 class(cond ) <- class [! duplicated(class , fromLast = TRUE )]
@@ -276,7 +341,7 @@ ConnectionMisuseFutureError <- function(...) {
276341
277342# ' @rdname FutureCondition
278343# ' @export
279- DeviceMisuseFutureCondition <- function (message = NULL , call = NULL , differences = NULL , uuid = future [[" uuid" ]], future = NULL ) {
344+ DeviceMisuseFutureCondition <- function (message = NULL , call = NULL , ... , differences = NULL , uuid = future [[" uuid" ]], future = NULL ) {
280345 if (is.null(message )) {
281346 label <- sQuoteLabel(future )
282347 message <- sprintf(" %s (%s) added, removed, or modified devices. A future expression must close any opened devices and must not close devices it did not open" , class(future )[1 ], label )
@@ -292,7 +357,7 @@ DeviceMisuseFutureCondition <- function(message = NULL, call = NULL, differences
292357 }
293358 message <- sprintf(" %s. See also help(\" future.options\" , package = \" future\" )" , message )
294359 }
295- cond <- FutureCondition(message = message , call = call , uuid = uuid , future = future )
360+ cond <- FutureCondition(message = message , call = call , ... , uuid = uuid , future = future )
296361 cond [[" differences" ]] <- differences
297362 class <- c(" DeviceMisuseFutureCondition" , " MisuseFutureCondition" , class(cond ))
298363 class(cond ) <- class [! duplicated(class , fromLast = TRUE )]
@@ -321,7 +386,7 @@ DeviceMisuseFutureError <- function(...) {
321386
322387# ' @rdname FutureCondition
323388# ' @export
324- DefaultDeviceMisuseFutureCondition <- function (message = NULL , incidents = NULL , call = NULL , uuid = future [[" uuid" ]], future = NULL ) {
389+ DefaultDeviceMisuseFutureCondition <- function (message = NULL , call = NULL , ... , incidents = NULL , uuid = future [[" uuid" ]], future = NULL ) {
325390 if (is.null(message )) {
326391 label <- sQuoteLabel(future )
327392 message <- sprintf(" %s (%s) opened the default graphics device" , class(future )[1 ], label )
@@ -340,7 +405,7 @@ DefaultDeviceMisuseFutureCondition <- function(message = NULL, incidents = NULL,
340405 message <- sprintf(" %s. This happens for instance if plot() is called without explicitly opening a graphics device before. Using default graphics devices in parallel processing will typically leave behind an 'Rplots.pdf' file on the parallel worker. If the intention is to plot to file, please open a graphics device explicitly (e.g. pdf() or png()) [recommended], or set your preferred `options(default = ...)` [not recommended], then plot, and make sure to close it at the end (i.e. dev.off())" , message )
341406 message <- sprintf(" %s. See also help(\" future.options\" , package = \" future\" )" , message )
342407 }
343- cond <- FutureCondition(message = message , call = call , uuid = uuid , future = future )
408+ cond <- FutureCondition(message = message , call = call , ... , uuid = uuid , future = future )
344409 class <- c(" DefaultDeviceMisuseFutureCondition" , " MisuseFutureCondition" , class(cond ))
345410 class(cond ) <- class [! duplicated(class , fromLast = TRUE )]
346411 cond
@@ -377,8 +442,8 @@ FutureLaunchError <- function(..., future = NULL) {
377442
378443# ' @rdname FutureCondition
379444# ' @export
380- FutureInterruptError <- function (... , future = NULL ) {
381- cond <- FutureError(... , future = future )
445+ FutureInterruptError <- function (... , when = Sys.time(), future = NULL ) {
446+ cond <- FutureError(... , when = when , future = future )
382447 class <- c(" FutureInterruptError" , class(cond ))
383448 class(cond ) <- class [! duplicated(class , fromLast = TRUE )]
384449 cond
@@ -387,7 +452,7 @@ FutureInterruptError <- function(..., future = NULL) {
387452# ' @rdname FutureCondition
388453# ' @export
389454FutureCanceledError <- function (... , future = NULL ) {
390- cond <- FutureError (... , future = future )
455+ cond <- FutureInterruptError (... , future = future )
391456 class <- c(" FutureCanceledError" , class(cond ))
392457 class(cond ) <- class [! duplicated(class , fromLast = TRUE )]
393458 cond
0 commit comments