> ## Documentation Index
> Fetch the complete documentation index at: https://docs.omophub.com/llms.txt
> Use this file to discover all available pages before exploring further.

# R SDK - Error handling and retries

> Handle OMOPHub API errors gracefully from the R SDK - catch rate-limit, authentication, and validation errors with retry-ready patterns for OHDSI work.

## Error Handling with tryCatch

The R SDK uses R's condition system for error handling. Use `tryCatch` to handle specific error types:

```r theme={null}
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:

```r theme={null}
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:

```r theme={null}
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")
  }
)
```

<Info>
  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.
</Info>

## Connection Errors

Handle network issues:

```r theme={null}
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

```r theme={null}
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

```r theme={null}
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:

```r theme={null}
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)
}
```
