When writing R code for use in production systems, it is
important to enclose chunks of code inside of try()
blocks. This is
especially important when processing user input or data obtained from web
services which may fail for a variety of reasons. If any problems arise
within a try()
block, it is important to generate informative and
consistent error messages.
Over the years, we have developed our own standard protocol for error handling that is easy to understand, easy to implement, and allows for consistent generation of error messages. To goal is to make it easy for developers to test sections of code that might fail and to create more uniform, more informative error messages than those that might come from deep within the R execution stack.
In addition to the generation of custom error messages, use of prefix
allows for the creation of classes of errors that can be detected and handled
appropriately as errors propagate to other functions.
stopOnError(
result,
err_msg = "",
prefix = "",
maxLength = 500,
truncatedLength = 120,
call. = FALSE
)
Return from a try()
block.
Custom error message.
Text string to add in front of the error message.
Maximum length of an error message. Error messages beyond this limit will be truncated.
Length of the output error message.
Logical indicating whether the call should become part of the error message.
Issues a stop()
with an appropriate error message.
If logging has been initialized, the customized/modified error message
will be logged with logger.error(err_msg)
before issuing
stop(err_msg)
.
The following examples show how to use this function:
library(MazamaCoreUtils)
# Arbitrarily deep in the stack we might have:
myFunc <- function(x) {
a <- log(x)
}
# Simple usage
userInput <- 10
result <- try({
myFunc(x = userInput)
}, silent = TRUE)
stopOnError(result)
userInput <- "ten"
result <- try({
myFunc(x = userInput)
}, silent = TRUE)
stopOnError(result)
# More concise code with the '%>%' operator
try({
myFunc(x = userInput)
}, silent = TRUE) %>%
stopOnError(err_msg = "Unable to process user input")
try({
myFunc(x = userInput)
}, silent = TRUE) %>%
stopOnError(prefix = "USER_INPUT_ERROR")
# Truncating error message length
try({
myFunc(x = userInput)
}, silent = TRUE) %>%
stopOnError(
prefix = "USER_INPUT_ERROR",
maxLength = 40,
truncatedLength = 32
)