r - 如何让main函数环境固定为 "anchor"?

标签 r error-handling callstack

在一个包中,我有一个 main 函数,它调用许多其他未导出的函数,并且到处都有大量条件检查。

当使用 tidyverse 错误处理时,例如使用 Awesome {cli}包中,您可以附加将用于装饰函数的调用者环境。该文档可用 here .

这里是一些示例代码:

main = function() f1()
f1 = function() f2()
f2 = function() cli::cli_abort("foobar", call=rlang::caller_env())
main()
#> Error in `f1()`:
#> ! foobar

reprex package 于 2022 年 7 月 3 日创建(v2.0.1)

调用者不是 f2() 而是其父 f1(),但该错误仍然不提供信息,因为最终用户不知道内部 f1() 函数之一。

要让 main() 作为最终调用者,我可以编写 call=rlang::caller_env(2) (这不太容易维护),或者传递调用者作为每个堆栈函数中的参数,这将需要大量重构。

有没有办法拥有一个全局变量来充当对 main() 的引用,并且我可以在代码中的任何位置使用它?

最佳答案

我能想到的唯一(hacky)选项:

1:继续一次向上 1 个父环境,直到到达 R_GlobalEnv,然后返回 1 步。

main = function() f1()
f1 = function() f2()

f2 = function() {
  for(depth in 1:10) if(identical(rlang::caller_env(depth), globalenv())) break
  if(depth == 10) depth = 1
  cli::cli_abort("foobar", call=rlang::caller_env(depth-1))
}
main()

2:自己创建某种可以搜索的标识符

main = function() {
  marker = "hello!"
  f1()
}
f1 = function() f2()
f2 = function() {
  for(depth in 1:10) try( if( get('marker', envir = rlang::caller_env(depth)) == "hello!" ) break, silent = T)
  if(depth == 10) depth = 0
  cli::cli_abort("foobar", call=rlang::caller_env(depth))
}
main()

关于r - 如何让main函数环境固定为 "anchor"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72844255/

相关文章:

regex - 提取字符串中括号之间的数字

c++ - 如何在不更改的情况下检索当前的 terminate() 处理程序?

php - 如何测试属性中是否存在方法?

powershell - 循环期间变量未重置会产生误导性输出

python - 在 Python 中,如何在保持原始调用堆栈的同时检查并重新引发异常?

r - 在调用堆栈中显示特殊的原始函数

r - R 上 Packrat 的问题

html - 编辑的 css 不会更改 rmarkdown xaringan 演示文稿

r - R :'expr' 中的曲线必须是函数、调用或包含 'x' 的表达式

c++ - 函数参数列表中的函数调用是否加深了堆栈?