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

# SpendOwlError

> SDK error types and handling

# SpendOwlError

Errors that can occur within the SpendOwl SDK.

```swift theme={null}
public enum SpendOwlError: LocalizedError, Sendable, Equatable
```

All SpendOwl operations are crash-proof. Errors are returned through completion handlers or thrown from async methods.

## Error Cases

### notConfigured

```swift theme={null}
case notConfigured
```

The SDK has not been configured.

**Error Code:** `1001`

**Solution:** Call `SpendOwl.configure(apiKey:)` before using other SDK methods.

```swift theme={null}
do {
    let attribution = try await SpendOwl.attribution()
} catch SpendOwlError.notConfigured {
    // Configure the SDK first
    SpendOwl.configure(apiKey: "your-api-key")
}
```

***

### invalidAPIKey

```swift theme={null}
case invalidAPIKey
```

The provided API key is invalid.

**Error Code:** `1002`

**Solution:** Check that you're using the correct API key from your [SpendOwl dashboard](https://spendowl.io/dashboard).

***

### networkError

```swift theme={null}
case networkError(Error)
```

A network error occurred.

**Error Code:** `2001`

**Associated Value:** The underlying network error.

**Notes:**

* The SDK automatically retries failed requests with exponential backoff
* This error is returned after all retry attempts have failed

```swift theme={null}
do {
    let attribution = try await SpendOwl.attribution()
} catch SpendOwlError.networkError(let underlyingError) {
    print("Network failed: \(underlyingError)")
    // Consider retrying later
}
```

***

### serverError

```swift theme={null}
case serverError(statusCode: Int, message: String?)
```

The server returned an error response.

**Error Code:** `2002`

**Associated Values:**

* `statusCode`: The HTTP status code
* `message`: An optional error message from the server

```swift theme={null}
do {
    let attribution = try await SpendOwl.attribution()
} catch SpendOwlError.serverError(let code, let message) {
    print("Server error \(code): \(message ?? "Unknown")")
}
```

***

### attributionUnavailable

```swift theme={null}
case attributionUnavailable
```

Attribution is not available on this device.

**Error Code:** `3001`

**Causes:**

* iOS version below 14.3
* AdServices framework not available
* Running in certain simulator configurations

**Solution:** This is expected on older devices. Handle gracefully.

***

### attributionDenied

```swift theme={null}
case attributionDenied
```

Attribution access was denied.

**Error Code:** `3002`

**Causes:**

* User has enabled "Limit Ad Tracking"
* MDM profile restricts ad tracking
* Device privacy settings

**Solution:** This is normal for some users. Continue without attribution data.

***

### encodingError

```swift theme={null}
case encodingError
```

Failed to encode request data.

**Error Code:** `4001`

**Notes:** This is an internal error that should not occur in normal operation. If it does, please report it.

***

### decodingError

```swift theme={null}
case decodingError(Error)
```

Failed to decode the server response.

**Error Code:** `4002`

**Associated Value:** The underlying decoding error.

**Solution:** This may indicate an API version mismatch. Update to the latest SDK version.

***

### unknown

```swift theme={null}
case unknown(Error)
```

An unknown error occurred.

**Error Code:** `9999`

**Associated Value:** The underlying error for debugging.

***

## Properties

### errorDescription

```swift theme={null}
public var errorDescription: String? { get }
```

A localized description of the error, suitable for display.

```swift theme={null}
catch let error as SpendOwlError {
    print(error.errorDescription ?? "Unknown error")
}
```

***

### errorCode

```swift theme={null}
public var errorCode: Int { get }
```

A unique error code for programmatic error handling.

| Code Range | Category                      |
| ---------- | ----------------------------- |
| 1000-1999  | Configuration errors          |
| 2000-2999  | Network/server errors         |
| 3000-3999  | Attribution errors            |
| 4000-4999  | Data encoding/decoding errors |
| 9000-9999  | Unknown errors                |

***

## Error Handling Examples

### Comprehensive Handling

```swift theme={null}
do {
    let attribution = try await SpendOwl.attribution()
    handleAttribution(attribution)
} catch SpendOwlError.notConfigured {
    // SDK not configured
    SpendOwl.configure(apiKey: "your-api-key")
    // Retry
} catch SpendOwlError.invalidAPIKey {
    // Wrong API key - log and alert
    logger.error("Invalid SpendOwl API key")
} catch SpendOwlError.networkError {
    // Network issue - will be retried automatically
    // Consider showing offline indicator
} catch SpendOwlError.serverError(let code, _) where code >= 500 {
    // Server issue - temporary, will resolve
} catch SpendOwlError.attributionUnavailable {
    // Device doesn't support attribution
    // Continue without attribution data
} catch SpendOwlError.attributionDenied {
    // User has tracking disabled
    // Continue without attribution data
} catch {
    // Unknown error
    logger.error("Attribution error: \(error)")
}
```

### Simple Handling

For most apps, simple error handling is sufficient:

```swift theme={null}
do {
    let attribution = try await SpendOwl.attribution()
    // Use attribution
} catch {
    // Log and continue without attribution
    print("Attribution unavailable: \(error.localizedDescription)")
}
```

### Completion Handler Pattern

```swift theme={null}
SpendOwl.attribution { result in
    switch result {
    case .success(let attribution):
        // Handle success
        break
    case .failure(let error):
        switch error {
        case .networkError:
            // Retry later
            break
        default:
            // Log error
            break
        }
    }
}
```

## Related

<CardGroup cols={2}>
  <Card title="Debugging" icon="bug" href="/sdk/debugging">
    Debug logging and troubleshooting
  </Card>

  <Card title="Troubleshooting" icon="wrench" href="/resources/troubleshooting">
    Common issues and solutions
  </Card>
</CardGroup>
