From 0e096d9ed747f4eba70c1688ddc302da4c552543 Mon Sep 17 00:00:00 2001 From: Yihui Xie Date: Sun, 28 Apr 2024 16:47:10 -0500 Subject: [PATCH] handle errors via options(error) instead of withCallingHandlers() to make it possible to call globalCallingHandlers(): https://github.com/yihui/knitr/issues/2324 --- R/knitr.R | 2 +- R/utils.R | 8 ++++++-- R/yaml.R | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/R/knitr.R b/R/knitr.R index f1708ad..b0bf9b1 100644 --- a/R/knitr.R +++ b/R/knitr.R @@ -15,7 +15,7 @@ csv_options = function(x) { x = one_string(x) res = handle_error( eval(parse_only(paste('alist(', quote_label(x), ')'))), - function(e, loc) { + function(loc) { if (loc != '') loc = paste(' at lines', loc) c( sprintf('Invalid syntax for chunk options%s:\n', loc), x, diff --git a/R/utils.R b/R/utils.R index a4f8ae5..9ac5177 100644 --- a/R/utils.R +++ b/R/utils.R @@ -343,10 +343,14 @@ func_name = function(which = 1) { handle_error = function( expr, handler, label = '', fun = getOption('xfun.handle_error.loc_fun') ) { - withCallingHandlers(expr, error = function(e) { + opts = options(error = function() { loc = if (is.function(fun)) trimws(fun(label)) else '' - message(one_string(handler(e, loc))) + # TODO: remove this workaround after knitr 1.47 + m = if (length(formals(handler)) == 1) handler(loc) else handler(list(message = ''), loc) + message(one_string(m)) }) + on.exit(options(opts)) + expr } # a shorthand for rm(list =, envir =) diff --git a/R/yaml.R b/R/yaml.R index 413d025..0809e3d 100644 --- a/R/yaml.R +++ b/R/yaml.R @@ -34,8 +34,8 @@ yaml_load = function( ) { if (use_yaml) return(handle_error( yaml::yaml.load(x, eval.expr = FALSE, handlers = yaml_handlers(handlers, envir), ...), - function(e, loc) { - s = e$message + function(loc) { + s = geterrmessage() r = 'line (\\d+), column (\\d+)' m = regmatches(s, regexec(r, s, perl = TRUE))[[1]] if (length(m) < 3) return()