use docaroo_rs::{
DocarooClient,
DocarooError,
models::PricingRequest
};
use std::{env, time::Duration};
use tokio::time::sleep;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let api_key = env::var("DOCAROO_API_KEY")
.unwrap_or_else(|_| "demo-key-for-testing".to_string());
let client = DocarooClient::new(api_key);
println!("Example 1: Handle invalid request");
println!("---------------------------------");
let invalid_request = PricingRequest::builder()
.npis(vec!["123".to_string()]) .condition_code("99214")
.build();
match client.pricing().get_in_network_rates(invalid_request).await {
Ok(_) => println!("Unexpected success"),
Err(e) => {
println!("Expected error occurred: {}", e);
match &e {
DocarooError::InvalidRequest(msg) => {
println!("Invalid request details: {}", msg);
}
_ => println!("Different error type: {:?}", e),
}
}
}
println!("\n\nExample 2: Handle authentication error");
println!("-------------------------------------");
let bad_client = DocarooClient::new("invalid-api-key");
let request = PricingRequest::builder()
.npis(vec!["1043566623".to_string()])
.condition_code("99214")
.build();
match bad_client.pricing().get_in_network_rates(request.clone()).await {
Ok(_) => println!("Unexpected success"),
Err(e) => {
match &e {
DocarooError::AuthenticationFailed(msg) => {
println!("Authentication failed: {}", msg);
println!("Action: Check your API key");
}
DocarooError::ApiError { code, message, request_id } => {
println!("API error ({}): {}", code, message);
if let Some(id) = request_id {
println!("Request ID for support: {}", id);
}
}
_ => println!("Error: {}", e),
}
}
}
println!("\n\nExample 3: Retry logic for transient errors");
println!("------------------------------------------");
let request = PricingRequest::builder()
.npis(vec!["1043566623".to_string()])
.condition_code("99214")
.build();
async fn call_with_retry(
client: &DocarooClient,
request: PricingRequest,
max_retries: u32,
) -> Result<(), DocarooError> {
let mut retries = 0;
loop {
match client.pricing().get_in_network_rates(request.clone()).await {
Ok(response) => {
println!("Success! Found {} NPIs with data", response.data.len());
return Ok(());
}
Err(e) => {
if e.is_retryable() && retries < max_retries {
retries += 1;
let delay = match &e {
DocarooError::RateLimitExceeded { retry_after } => {
println!("Rate limit hit. Waiting {} seconds...", retry_after);
Duration::from_secs(*retry_after)
}
_ => {
let backoff = Duration::from_secs(2u64.pow(retries));
println!("Retryable error: {}. Retry {} of {} in {:?}...",
e, retries, max_retries, backoff);
backoff
}
};
sleep(delay).await;
continue;
} else {
println!("Non-retryable error or max retries reached: {}", e);
return Err(e);
}
}
}
}
}
let _ = call_with_retry(&client, request, 3).await;
println!("\n\nExample 4: Comprehensive error information");
println!("-----------------------------------------");
let test_cases = vec![
(
PricingRequest::builder()
.npis(vec![]) .condition_code("99214")
.build(),
"Empty NPIs list"
),
(
PricingRequest::builder()
.npis((0..15).map(|i| format!("{:010}", i)).collect::<Vec<String>>()) .condition_code("99214")
.build(),
"Too many NPIs"
),
(
PricingRequest::builder()
.npis(vec!["ABCDEFGHIJ".to_string()]) .condition_code("99214")
.build(),
"Non-numeric NPI"
),
];
for (request, description) in test_cases {
println!("\nTesting: {}", description);
match client.pricing().get_in_network_rates(request).await {
Ok(_) => println!(" Unexpected success"),
Err(e) => {
println!(" Error: {}", e);
if let Some(request_id) = e.request_id() {
println!(" Request ID: {}", request_id);
}
println!(" Is retryable: {}", e.is_retryable());
}
}
}
Ok(())
}