> ## 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 Flutter SDK.

## Exception Hierarchy

```
Law4DevsException (base)
├── NotFoundError       (404)
├── ValidationError     (400)
├── RateLimitError      (429)
└── ServerError         (5xx)
```

All exceptions implement Dart's `Exception` interface and expose `message` and `statusCode`.

***

## Catching Errors

```dart theme={null}
import 'package:law4devs/law4devs.dart';

try {
  final fw = await client.frameworks.get('nonexistent');
} on NotFoundError catch (e) {
  print('404: ${e.message}');
} on ValidationError catch (e) {
  print('400: ${e.message}');
} on RateLimitError catch (e) {
  print('429: Rate limited — SDK retried automatically');
} on ServerError catch (e) {
  print('${e.statusCode}: ${e.message}');
} on Law4DevsException catch (e) {
  print('API error ${e.statusCode}: ${e.message}');
}
```

***

## 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

```dart theme={null}
Future<FrameworkDetail?> safeGet(Law4DevsClient client, String slug) async {
  try {
    return await client.frameworks.get(slug);
  } on NotFoundError {
    return null;
  }
}

final fw = await safeGet(client, 'unknown-slug');
if (fw != null) {
  print(fw.name);
}
```

***

## Error Properties

| Property     | Type     | Description                |
| ------------ | -------- | -------------------------- |
| `message`    | `String` | Error message from the API |
| `statusCode` | `int?`   | HTTP status code           |
