1

我正在构建一个包,我希望更好地控制错误消息

我读过哈德利关于处理异常的章节,但我还是迷路了

这是一个简单的例子:

myfunc = function(x){
  intial_result = x + 1
  final_result = initial_result + 1
  return(final_result)
}

如果你运行myfunc("1")你会得到错误:

> myfunc("1")
Error in x + 1 : non-numeric argument to binary operator

但这并没有告诉用户错误发生在哪里。

所以我尝试使用tryCatch,它的工作原理是:

myfunc = function(x){
  r = tryCatch(
    expr = {x + 1},
    error = function(e){
      message = paste0("argument must be a number", "\nFor example, x = 2")
      e = simpleError(message)
      stop(e)
    }
  )
  r2 = r + 1
  return(r2)
}

但这是处理自定义错误消息的最佳方式吗?

此外,有没有办法只抛出一个message()并且仍然stop()是程序?(因为stop()会激活调试器)

编辑我希望有像以下错误消息dplyr

library(dplyr)
data('starwars')
select(starwars, x)
Error: Can't subset columns that don't exist.
x Column `x` doesn't exist.
Run `rlang::last_error()` to see where the error occur
4

2 回答 2

3

您可能会发现类似断言函数的东西很有用。

在最简单的情况下,它检查条件是否为真,否则抛出错误。

assert <- function(condition, msg){
  if(condition == FALSE)
    stop(msg)
}

使用示例:

myfunc = function(x){
  assert(is.numeric(x), "input 'x' to 'myfunc' was not numeric")
  intial_result = x + 1
  final_result = initial_result + 1
  return(final_result)
}

如果这是您需要的,那么有一个完整的 R 包用于此目的:assertthat,您可能会想要该assert_that函数。

dplyr 似乎使用了该assertr软件包,因此您可能还想对此进行调查。

于 2020-11-04T22:23:23.513 回答
1

上面的答案很好

我浏览了 dplyr github repo 并看到它使用了rlang一些东西

这将返回一个 tidyverse 样式错误:

myfunc = function(x){
  initial_result = rlang::with_handlers(
    .expr = x + 1,
    error = ~ rlang::abort(c("you did it wrong", x = "`x` should be a number", i = "For example: `x = 2`")))
  final_result = initial_result + 1
  return(final_result)
}

> myfunc(a)
Error: you did it wrong
x `x` should be a number
i For example: `x = 2`
Run `rlang::last_error()` to see where the error occurred.
于 2020-11-04T23:33:30.070 回答