@@ -11,13 +11,10 @@ source_many <- function(files, encoding = "UTF-8", envir = parent.frame()) {
11
11
for (file in files ) {
12
12
try_fetch(
13
13
source_one(file , encoding , envir = envir ),
14
- error = function (cnd ) {
15
- path <- file.path(basename(dirname(file )), basename(file ))
16
- msg <- paste0(" Failed to load {.file {path}}" )
17
- cli :: cli_abort(msg , parent = cnd , call = quote(load_all()))
18
- }
14
+ error = function (cnd ) handle_source_error(cnd , file )
19
15
)
20
16
}
17
+
21
18
invisible ()
22
19
}
23
20
@@ -26,15 +23,49 @@ source_one <- function(file, encoding, envir = parent.frame()) {
26
23
stopifnot(is.environment(envir ))
27
24
28
25
lines <- read_lines_enc(file , file_encoding = encoding )
29
- srcfile <- srcfilecopy(file , lines , file.info(file )[1 , " mtime" ],
30
- isFile = TRUE )
31
- exprs <- parse(text = lines , n = - 1 , srcfile = srcfile )
26
+ srcfile <- srcfilecopy(file , lines , file.info(file )[1 , " mtime" ], isFile = TRUE )
32
27
33
- n <- length(exprs )
34
- if (n == 0L ) return (invisible ())
28
+ withCallingHandlers(
29
+ exprs <- parse(text = lines , n = - 1 , srcfile = srcfile ),
30
+ error = function (cnd ) handle_parse_error(cnd , file )
31
+ )
35
32
36
- for (i in seq_len( n ) ) {
37
- eval(exprs [ i ] , envir )
33
+ for (expr in exprs ) {
34
+ eval(expr , envir )
38
35
}
36
+
39
37
invisible ()
40
38
}
39
+
40
+ handle_source_error <- function (cnd , file ) {
41
+ path <- file.path(basename(dirname(file )), basename(file ))
42
+ msg <- paste0(" Failed to load {.file {path}}" )
43
+ cli :: cli_abort(msg , parent = cnd , call = quote(load_all()))
44
+ }
45
+
46
+ handle_parse_error <- function (cnd , file ) {
47
+ path <- file.path(basename(dirname(file )), basename(file ))
48
+
49
+ # Tweak base message to be shorter and add link to src location.
50
+ msg <- conditionMessage(cnd )
51
+
52
+ # Extract :<line>:<col> in base message.
53
+ location <- regmatches(msg , m = regexpr(" \\ :\\ d+\\ :\\ d+" , msg ))
54
+
55
+ if (length(location ) == 0 ) {
56
+ return (zap())
57
+ }
58
+
59
+ suffixed_path <- paste0(path , location )
60
+
61
+ # Tweak parse() message to include an hyperlink.
62
+ # Replace full path by relative path + hyperlink
63
+ path_hyperlink <- cli :: format_inline(paste0(" At {.file " , suffixed_path , " }:" ))
64
+ msg <- sub(
65
+ paste0(" ^.*" , suffixed_path , " \\ :" ),
66
+ path_hyperlink ,
67
+ msg
68
+ )
69
+
70
+ abort(msg , call = conditionCall(cnd ))
71
+ }
0 commit comments