src/dot-agents/skills/r-error-handling/SKILL.md
Base R error handling with tryCatch, withCallingHandlers, and custom condition classes. Use when implementing error recovery, debugging conditions, or working with stop/warning/message—e.g., "tryCatch in R", "custom condition class", "handle warnings and errors", "error recovery patterns".
npx skillsauth add jjjermiah/dotagents r-error-handlingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Production-grade error handling and custom condition classes in R. Guide structured errors, input validation, error chaining, and graceful recovery.
We follow one principle: Fail fast, fail informatively.
Every error handling implementation MUST:
# Basic error with call context
check_positive <- function(x, arg = rlang::caller_arg(x), call = rlang::caller_env()) {
if (any(x <= 0)) {
rlang::abort(
sprintf("`%s` must be positive.", arg),
class = "mypackage_validation_error",
call = call
)
}
}
# Error chaining
download_data <- function(url, call = rlang::caller_env()) {
rlang::try_fetch(
fetch_and_parse(url),
error = function(cnd) {
rlang::abort(
sprintf("Failed to download from %s", url),
class = "mypackage_download_error",
parent = cnd, # Chains original error
call = call
)
}
)
}
# Structured messages
rlang::abort(c(
"Required columns missing.",
x = "Column 'id' not found",
i = "Available: name, age, city"
))
# Simple error
validate_input <- function(x) {
if (!valid(x)) {
stop("Invalid input", call. = FALSE)
}
}
# Error recovery
result <- tryCatch(
risky_operation(),
error = function(e) {
message("Error: ", e$message)
default_value
}
)
Format: {package}_{domain}_{type}
"mypackage_validation_invalid_type"
"mypackage_io_file_not_found"
check_string <- function(x, arg = rlang::caller_arg(x), call = rlang::caller_env()) {
if (!is.character(x) || length(x) != 1) {
rlang::abort(
sprintf("`%s` must be a single string.", arg),
class = "mypackage_validation_error",
call = call
)
}
}
# Auto-detects argument name
my_function <- function(file_path) {
check_string(file_path) # Error shows "file_path"
}
result <- rlang::try_fetch(
operation(),
mypackage_network_error = function(cnd) { get_cached_data() },
error = function(cnd) { log_error(cnd); rlang::zap() }
)
# In R/errors.R
abort_mypackage <- function(message, class, ..., call = rlang::caller_env()) {
rlang::abort(
message,
class = paste0("mypackage_", class),
...,
call = call
)
}
# Usage
check_input <- function(x, call = rlang::caller_env()) {
if (!valid(x)) {
abort_mypackage("Invalid input", class = "validation_error", call = call)
}
}
# Bullet types:
# i = info (blue)
# x = error (red X)
# v = success (green check)
# ! = warning (yellow)
# * = regular
rlang::abort(c(
"Multiple validation errors:",
x = "Field 'id' is missing",
x = "Field 'name' is invalid",
i = "See ?required_fields for details"
))
| Use Case | Tool | Notes |
| ----------------- | ---------------------------------------- | -------------------- |
| New package | try_fetch() + abort() | Modern, powerful |
| Zero dependencies | tryCatch() + stop() | Acceptable tradeoff |
| Error chaining | parent arg | Preserves context |
| Input validation | caller_arg() + abort() | Readable messages |
| Error recovery | try_fetch() | Better than tryCatch |
| Stack inspection | try_fetch() or withCallingHandlers() | Both preserve stack |
These patterns ALWAYS cause failures in production. No exceptions.
NEVER:
tryCatch(x, error = function(e) NULL) — debugging becomes impossibleabort("Error") — breaks selective handlingcall argument: abort_mypackage("Error") — shows wrong function in traceback, every timeparent — loses critical contextALWAYS:
log_error(cnd); return(fallback)class = "mypackage_specific_error"call = caller_env()parent = cnd# Test error class
testthat::test_that("validates input", {
testthat::expect_error(
my_function(bad_input),
class = "mypackage_validation_error"
)
})
# Snapshot error messages
testthat::test_that("error messages are clear", {
testthat::expect_snapshot(error = TRUE, {
my_function(bad_input)
})
})
# Inspect error metadata
testthat::test_that("error has correct fields", {
err <- rlang::catch_cnd(my_function(bad_input))
testthat::expect_equal(err$field, "x")
testthat::expect_equal(err$expected, "numeric")
})
Before finishing any task with this skill, verify ALL of the following:
rlang::abort() with custom classes (never library(rlang))call = rlang::caller_env()parent = cndChecking these items is required. Skipped verification = broken error handling in production.
development
Guides creation, validation, and packaging of AI agent skills with token-efficient design, progressive disclosure patterns, and YAML frontmatter best practices. Use when building new skills, updating existing skills, validating skill structure against standards, or packaging for distribution—e.g., "create skill", "validate SKILL.md", "package skill for sharing", "check description format".
tools
Investigate and integrate weakly documented SDK/library modules (especially Azure SDKs) into code. Use when asked to "investigate module", "SDK", "client class", or when docs are missing/weak and you need to discover APIs, models, or usage patterns to implement integration.
tools
Write production-ready one-off scripts and automation utilities with proper error handling and safety patterns. Use when developing bash automation, Python CLI tools, shell scripts, system administration scripts, or command-line batch processing—e.g., "write a script to process files", "python one-liner for data conversion", "bash automation for backups", "shell script with error handling".
development
R package testing with testthat 3rd edition. Use when writing R tests, fixing failing tests, debugging errors, or reviewing coverage—e.g., "write testthat tests", "fix failing R tests", "snapshot testing", "test coverage".