Error Handling with tryCatch
The R SDK uses R’s condition system for error handling. Use tryCatch to handle specific error types:
library(omophub)
client <- OMOPHubClient$new(api_key = "oh_xxx")
tryCatch(
{
concept <- client$concepts$get(999999999)
},
omophub_not_found = function(e) {
cat(sprintf("Not found: %s\n", e$message))
},
omophub_auth_error = function(e) {
cat(sprintf("Auth failed: %s\n", e$message))
},
omophub_rate_limit_error = function(e) {
cat(sprintf("Rate limited. Retry after %ds\n", e$retry_after))
},
omophub_api_error = function(e) {
cat(sprintf("API error %d: %s\n", e$status_code, e$message))
}
)
Error Types
The SDK defines the following error conditions:
omophub_error # Base error for all SDK errors
├── omophub_api_error # API returned an error response
│ ├── omophub_auth_error # 401 - Invalid or missing API key
│ ├── omophub_not_found # 404 - Resource not found
│ ├── omophub_validation_error # 400 - Invalid request parameters
│ ├── omophub_rate_limit_error # 429 - Too many requests
│ └── omophub_server_error # 500+ - Server-side error
└── omophub_connection_error # Network connectivity issues
Error Properties
All errors include helpful properties:
tryCatch(
{
concept <- client$concepts$get(999999999)
},
omophub_api_error = function(e) {
print(e$message) # Human-readable error message
print(e$status_code) # HTTP status code
print(e$request_id) # Request ID for debugging
}
)
Rate Limiting
Handle rate limits with retry logic:
tryCatch(
{
results <- client$search$basic("diabetes")
},
omophub_rate_limit_error = function(e) {
cat(sprintf("Rate limited. Retry after %d seconds\n", e$retry_after))
Sys.sleep(e$retry_after)
# Retry the request
results <- client$search$basic("diabetes")
}
)
The SDK automatically retries failed requests up to max_retries times (default: 3) with exponential backoff. You typically don’t need to handle transient errors manually.
Connection Errors
Handle network issues:
tryCatch(
{
concept <- client$concepts$get(201826)
},
omophub_connection_error = function(e) {
cat(sprintf("Network error: %s\n", e$message))
# Implement your retry logic or fallback
}
)
Best Practices
Catch Specific Errors First
tryCatch(
{
concept <- client$concepts$get(concept_id)
},
omophub_not_found = function(e) {
# Handle missing concept
concept <- NULL
},
omophub_rate_limit_error = function(e) {
# Wait and retry
Sys.sleep(e$retry_after)
},
omophub_api_error = function(e) {
# Log and handle other API errors
warning(sprintf("API error: %s", e$message))
stop(e)
}
)
Use withCallingHandlers for Logging
withCallingHandlers(
{
results <- client$search$basic("diabetes")
},
omophub_api_error = function(e) {
# Log but don't handle - let it propagate
message(sprintf("API call failed: %s", e$message))
}
)
Wrap in a Safe Function
Create a helper function for common error handling:
safe_get_concept <- function(client, concept_id) {
tryCatch(
{
client$concepts$get(concept_id)
},
omophub_not_found = function(e) {
NULL
},
omophub_api_error = function(e) {
warning(sprintf("Failed to get concept %d: %s", concept_id, e$message))
NULL
}
)
}
# Usage
concept <- safe_get_concept(client, 201826)
if (!is.null(concept)) {
print(concept$concept_name)
}