22.6 Non-error failures

There are other ways for a function to fail apart from throwing an error:

  • A function may generate an unexpected warning. The easiest way to track down warnings is to convert them into errors with options(warn = 2) and use the the call stack, like doWithOneRestart(), withOneRestart(), regular debugging tools. When you do this you’ll see some extra calls withRestarts(), and .signalSimpleWarning(). Ignore these: they are internal functions used to turn warnings into errors.

  • A function may generate an unexpected message. You can use rlang::with_abort() to turn these messages into errors:

    f <- function() g()
    g <- function() message("Hi!")
    f()
    #> Hi!
    
    rlang::with_abort(f(), "message")
    #> Error: Hi!
    rlang::last_trace()
    #> Error: Can't show last error because no error was recorded yet
  • A function might never return. This is particularly hard to debug automatically, but sometimes terminating the function and looking at the traceback() is informative. Otherwise, use use print debugging, as in Section 22.5.2.

  • The worst scenario is that your code might crash R completely, leaving you with no way to interactively debug your code. This indicates a bug in compiled (C or C++) code.

    If the bug is in your compiled code, you’ll need to follow the links in Section 22.4.3 and learn how to use an interactive C debugger (or insert many print statements).

    If the bug is in a package or base R, you’ll need to contact the package maintainer. In either case, work on making the smallest possible reproducible example (Section 1.7) to help the developer help you.