Skip to main content

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)
}