@@ -743,9 +743,20 @@ getStackTrace <- function(expr, debug = FALSE, prune_errors = TRUE) {
743
743
error = function (e ) {
744
744
if (is.null(attr(e , " stack.trace" , exact = TRUE ))) {
745
745
calls <- sys.calls()
746
+ reverseStack <- rev(calls )
746
747
attr(e , " stack.trace" ) <- calls
747
- errorCall <- e $ call [[1 ]]
748
-
748
+
749
+ if (! is.null(e $ call [[1 ]]))
750
+ errorCall <- e $ call [[1 ]]
751
+ else {
752
+ # attempt to capture the error or warning if thrown by
753
+ # simpleError or simpleWarning (which may arise for user-defined errors)
754
+ #
755
+ # the first matching call in the reversed stack will always be
756
+ # getStackTrace, so we select the second match instead
757
+ errorCall <- reverseStack [grepl(x = reverseStack , " simpleError|simpleWarning" )][[2 ]]
758
+ }
759
+
749
760
functionsAsList <- lapply(calls , function (completeCall ) {
750
761
currentCall <- completeCall [[1 ]]
751
762
@@ -760,8 +771,6 @@ getStackTrace <- function(expr, debug = FALSE, prune_errors = TRUE) {
760
771
761
772
})
762
773
763
- reverseStack <- rev(calls )
764
-
765
774
if (prune_errors ) {
766
775
# this line should match the last occurrence of the function
767
776
# which raised the error within the call stack; prune here
@@ -779,14 +788,18 @@ getStackTrace <- function(expr, debug = FALSE, prune_errors = TRUE) {
779
788
# to stop at the correct position.
780
789
if (is.function(currentCall [[1 ]])) {
781
790
identical(deparse(errorCall ), deparse(currentCall [[1 ]]))
782
- } else {
791
+ } else if (currentCall [[1 ]] == " stop" ) {
792
+ # handle case where function developer deliberately invokes a stop
793
+ # condition and halts function execution
794
+ identical(deparse(errorCall ), deparse(currentCall ))
795
+ }
796
+ else {
783
797
FALSE
784
798
}
785
799
786
800
}
787
801
)
788
802
)
789
-
790
803
# the position to stop at is one less than the difference
791
804
# between the total number of calls and the index of the
792
805
# call throwing the error
@@ -797,12 +810,14 @@ getStackTrace <- function(expr, debug = FALSE, prune_errors = TRUE) {
797
810
functionsAsList <- removeHandlers(functionsAsList )
798
811
}
799
812
813
+ # use deparse in case the call throwing the error is a symbol,
814
+ # since this cannot be "printed" without deparsing the call
800
815
warning(call. = FALSE , immediate. = TRUE , sprintf(" Execution error in %s: %s" ,
801
- functionsAsList [[length(functionsAsList )]],
816
+ deparse( functionsAsList [[length(functionsAsList )]]) ,
802
817
conditionMessage(e )))
803
818
804
819
stack_message <- stackTraceToHTML(functionsAsList ,
805
- functionsAsList [[length(functionsAsList )]],
820
+ deparse( functionsAsList [[length(functionsAsList )]]) ,
806
821
conditionMessage(e ))
807
822
808
823
assign(" stack_message" , value = stack_message ,
0 commit comments