Skip to content

Commit 3580d9f

Browse files
committed
Use withCallingHandler when wrapping errors
instead of tryCatch to ensure that the error is handled correctly. This is considered best practice (More information error when `quarto_run()` fails #184).
1 parent 9901418 commit 3580d9f

File tree

1 file changed

+66
-49
lines changed

1 file changed

+66
-49
lines changed

R/quarto.R

Lines changed: 66 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,12 @@ quarto_available <- function(min = NULL, max = NULL, error = FALSE) {
9797
error = function(e) NULL
9898
)
9999
if (!is.null(quarto_version)) {
100-
if (!is.null(min)) is_above <- quarto_version >= min
101-
if (!is.null(max)) is_below <- quarto_version <= max
100+
if (!is.null(min)) {
101+
is_above <- quarto_version >= min
102+
}
103+
if (!is.null(max)) {
104+
is_below <- quarto_version <= max
105+
}
102106
found <- is_above && is_below
103107
}
104108
if (!found && error) {
@@ -134,50 +138,19 @@ quarto_run <- function(
134138
if (!quarto_available(min = "1.8.13")) {
135139
custom_env <- c("current", QUARTO_R = R.home("bin"))
136140
}
137-
res <- tryCatch(
138-
{
139-
processx::run(
140-
quarto_bin,
141-
args = args,
142-
echo = echo,
143-
error_on_status = TRUE,
144-
echo_cmd = echo_cmd,
145-
env = custom_env,
146-
...
147-
)
148-
},
149-
error = function(e) {
150-
if (!inherits(e, "system_command_status_error")) {
151-
cli::cli_abort(
152-
c("!" = "Error running quarto CLI from R."),
153-
call = .call,
154-
parent = e
155-
)
156-
} else {
157-
msg <- c(x = "Error returned by quarto CLI.")
158-
# if there is an error message from quarto CLI, add it to the message
159-
if (e$stderr != "") {
160-
quarto_error_msg <- xfun::split_lines(e$stderr)
161-
names(quarto_error_msg) <- rep(" ", length(quarto_error_msg))
162-
msg <- c(
163-
msg,
164-
" " = paste0(rep("-", nchar(msg)), collapse = ""),
165-
quarto_error_msg
166-
)
167-
}
168-
169-
# if `--quiet` has been set, quarto CLI won't report any error (e$stderr will be empty)
170-
# So remind user to run without `--quiet` to see the full error message
171-
if (cli_arg_quiet() %in% args)
172-
msg <- c(
173-
msg,
174-
"i" = "Rerun with `quiet = FALSE` to see the full error message."
175-
)
176-
177-
cli::cli_abort(msg, call = .call, parent = e)
178-
}
179-
}
141+
res <- withCallingHandlers(
142+
processx::run(
143+
quarto_bin,
144+
args = args,
145+
echo = echo,
146+
error_on_status = TRUE,
147+
echo_cmd = echo_cmd,
148+
env = custom_env,
149+
...
150+
),
151+
error = function(cnd) wrap_quarto_error(cnd, args, .call = .call)
180152
)
153+
181154
invisible(res)
182155
}
183156

@@ -223,16 +196,20 @@ is_using_quarto <- function(dir = ".", verbose = FALSE) {
223196
0
224197
has_qmd <- length(list.files(dir, pattern = "\\.qmd$", full.names = TRUE)) > 0
225198
if (has_quarto_yml) {
226-
if (verbose) cli::cli_inform("A {.file _quarto.yml} has been found.")
199+
if (verbose) {
200+
cli::cli_inform("A {.file _quarto.yml} has been found.")
201+
}
227202
return(TRUE)
228203
} else if (has_qmd) {
229-
if (verbose)
204+
if (verbose) {
230205
cli::cli_inform("At least one file {.code *.qmd} has been found.")
206+
}
231207
return(TRUE)
232208
}
233209
# not a directory using Quarto
234-
if (verbose)
210+
if (verbose) {
235211
cli::cli_inform("No {.file _quarto.yml} or {.code *.qmd} has been found.")
212+
}
236213
return(FALSE)
237214
}
238215

@@ -274,7 +251,9 @@ quarto_binary_sitrep <- function(verbose = TRUE, debug = FALSE) {
274251
quarto_found <- normalizePath(quarto_found, mustWork = FALSE)
275252

276253
same_config <- TRUE
277-
if (debug) verbose <- TRUE
254+
if (debug) {
255+
verbose <- TRUE
256+
}
278257

279258
# Quarto R package situation ----
280259
if (verbose) {
@@ -326,3 +305,41 @@ quarto_binary_sitrep <- function(verbose = TRUE, debug = FALSE) {
326305

327306
return(same_config)
328307
}
308+
309+
310+
wrap_quarto_error <- function(cnd, args, .call = rlang::caller_env()) {
311+
if (!inherits(commandArgs(), "system_command_status_error")) {
312+
cli::cli_abort(
313+
c("!" = "Error running quarto CLI from R."),
314+
call = .call,
315+
parent = cnd
316+
)
317+
} else {
318+
msg <- c(x = "Error running quarto cli.")
319+
# if there is an error message from quarto CLI, add it to the message
320+
if (cnd$stderr != "") {
321+
quarto_error_msg <- xfun::split_lines(cnd$stderr)
322+
names(quarto_error_msg) <- rep(" ", length(quarto_error_msg))
323+
msg <- c(
324+
msg,
325+
" " = paste0(rep("-", nchar(msg)), collapse = ""),
326+
quarto_error_msg
327+
)
328+
}
329+
330+
# if `--quiet` has been set, quarto CLI won't report any error (cnd$stderr will be empty)
331+
# So remind user to run without `--quiet` to see the full error message
332+
if (cli_arg_quiet() %in% args) {
333+
msg <- c(
334+
msg,
335+
"i" = "Rerun with `quiet = FALSE` to see the full error message."
336+
)
337+
}
338+
339+
cli::cli_abort(
340+
msg,
341+
call = .call,
342+
parent = cnd,
343+
)
344+
}
345+
}

0 commit comments

Comments
 (0)