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

# Error Handling

> Handle API errors gracefully with the Rust SDK.

## Error Enum

```
Law4DevsError
├── NotFound(String)       — 404 Not Found
├── Validation(String)     — 400 Bad Request
├── RateLimit              — 429 Too Many Requests
├── Server(u16, String)    — 5xx Server Error
├── Network(reqwest::Error)— Network/timeout failure
└── Parse(serde_json::Error)— JSON deserialization failure
```

`Law4DevsError` implements `std::error::Error` and `Display` via `thiserror`.

***

## Matching Errors

```rust theme={null}
use law4devs::{Law4DevsClient, Law4DevsError};

match client.frameworks.get("nonexistent").await {
    Ok(fw) => println!("{}", fw.name),
    Err(Law4DevsError::NotFound(msg))       => eprintln!("404: {msg}"),
    Err(Law4DevsError::Validation(msg))     => eprintln!("400: {msg}"),
    Err(Law4DevsError::RateLimit)           => eprintln!("429: rate limited"),
    Err(Law4DevsError::Server(code, msg))   => eprintln!("{code}: {msg}"),
    Err(Law4DevsError::Network(e))          => eprintln!("network: {e}"),
    Err(e)                                  => eprintln!("other: {e}"),
}
```

***

## With `?` Propagation

```rust theme={null}
async fn get_cra_articles(client: &Law4DevsClient) -> Result<Vec<ArticleSummary>, Law4DevsError> {
    let page = client.articles.list("cra", None, Some(50)).await?;
    Ok(page.data)
}
```

***

## Retry Behavior

The SDK automatically retries `429` and `5xx` responses with exponential backoff:

| Attempt   | Delay     |
| --------- | --------- |
| 1st retry | 1 second  |
| 2nd retry | 2 seconds |
| 3rd retry | 4 seconds |

`404` and `400` are thrown immediately without retrying.

***

## Safe Get Pattern

```rust theme={null}
async fn safe_get(client: &Law4DevsClient, slug: &str) -> Option<law4devs::FrameworkDetail> {
    match client.frameworks.get(slug).await {
        Ok(fw) => Some(fw),
        Err(Law4DevsError::NotFound(_)) => None,
        Err(e) => { eprintln!("Error: {e}"); None }
    }
}
```

***

## Streams and Errors

Each item in an `iter()` stream is a `Result<T, Law4DevsError>`. A single failed page stops the stream:

```rust theme={null}
use futures::StreamExt;

let mut stream = Box::pin(client.articles.iter("gdpr", 20));
while let Some(result) = stream.next().await {
    match result {
        Ok(a)  => println!("{}", a.title),
        Err(e) => { eprintln!("Stream error: {e}"); break; }
    }
}
```
