# Handle Structured Errors

This guide covers how to deal with structured errors encountered while downloading offline map packages. Offline Maps operations can report errors through the _downloadRegion_ completion handler before a task is accepted, and through `progress.error` after a task has been enqueued.

Since, in Swift, `progress.error` is exposed as `Error?`. Cast it to _NSError_ to read the Offline Maps error domain, code, and diagnostic `userInfo` values.

```swift
func handleRegionalOfflineError(_ error: Error?) {
    guard let error else { return }
 
    let nsError = error as NSError
 
    guard nsError.domain == NGLRegionalOfflineErrorDomain else {
        print("Unexpected error: \(nsError)")
        return
    }
 
    let code = NGLRegionalOfflineError.Code(rawValue: nsError.code)
 
    switch code {
    case .networkUnavailable:
        // Ask the user to check the network connection.
        break
 
    case .requestTimedOut:
        // Offer a retry action.
        break
 
    case .httpStatus:
        let statusCode =
            nsError.userInfo[NGLRegionalOfflineErrorHTTPStatusCodeKey] as? Int
        print("HTTP status: \(statusCode ?? 0)")
 
    case .insufficientStorage:
        // Ask the user to free device storage.
        break
    case .unsupportedTileServer:
        // Switch NGLAccountManager to NGLTomTom before using Regional Offline.
        break
 
    case .invalidPackage, .packageDecompression, .packageInstallation:
        // Retry the download and report persistent package failures.
        break
 
    default:
        break
    }
 
    let requestURL =
        nsError.userInfo[NGLRegionalOfflineErrorURLKey] as? String
    let packageName =
        nsError.userInfo[NGLRegionalOfflineErrorPackageNameKey] as? String
 
    print(
        "Regional offline failed: " +
        "domain=\(nsError.domain) " +
        "code=\(nsError.code) " +
        "package=\(packageName ?? "-") " +
        "url=\(requestURL ?? "-") " +
        "message=\(nsError.localizedDescription)"
    )
}
```

Following is the table with references for errors:

| Swift error code | Meaning | Recommended action |
| --- | --- | --- |
| `.network` | Unclassified network error | Check connectivity and retry |
| `.networkUnavailable` | No connection, DNS failure, or host connection failure | Wait for connectivity |
| `.requestTimedOut` | Request timed out | Offer retry |
| `.httpStatus` | Non-2xx HTTP response | Record the HTTP status and verify the service |
| `.invalidResponse` | Invalid catalog or region response | Verify server data |
| `.storage` | Generic storage error | Check device storage |
| `.fileSystem` | File create, read, or write failure | Check storage and retry |
| `.insufficientStorage` | Insufficient free storage | Ask the user to free space |
| `.invalidPackage` | Corrupt or unsupported package | Retry or verify the server package |
| `.packageDecompression` | Package decompression failed | Retry the download |
| `.packageInstallation` | Package installation failed | Check storage and retry |
| `.invalidRegion` | Invalid or unknown region | Refresh the catalog |
| `.previewNotReady` | Shared preview resources are not ready | Wait for resource preparation |
| `.styleNotCached` | The offline style is not cached | Use an SDK offline style and prepare preview resources |
| `.noInstalledRegions` | No installed region is available | Ask the user to download a region |
| `.cancelled` | Download was cancelled or paused | Resume according to the product flow |
| `.unknown` | Unclassified or legacy error | Record the complete error |
| `.downloadAlreadyActive` | The same region already has an active task | Reuse, wait for, cancel, or delete the existing task |
| `.previewDatabaseOpen` | The native engine could not open the validated Preview database | Keep the task incomplete and record the database path and underlying error |
| `.previewRollbackFailed` | Preview activation failed and rollback was incomplete | Stop completion and record the rollback error array |
| `.unsupportedTileServer` | The active tile server has no supported Regional Offline packages | Select NGLTomTom before configuring or using Regional Offline |

> `progress.errorMessage` _remains available for compatibility. New integrations should use_ `progress.error`_._
