Error Handling
Every SDK failure arrives as an SdkError with four fields you can act on immediately:
AnylineTireTread.getResult(measurementUUID = uuid, timeoutSeconds = 60) { response ->
when (response) {
is SdkResult.Ok -> renderResult(response.result)
is SdkResult.Err -> {
val error = response.error
Log.e("TTR", "type=${error.type} code=${error.code} message=${error.message}")
error.debug?.let { Log.d("TTR", "debug=$it") }
handleError(error)
}
}
}
Error Object
SdkError uses ErrorType and ErrorCode enums to categorize failures:
| Field | How to use it |
|---|---|
|
Determines the recovery strategy. Branch your error handling on this field first. |
|
Identifies the precise condition within the type. Use it for logging, analytics, and fine-grained handling when needed. |
|
A human-readable description. |
|
Optional platform-specific details for logging and diagnostics. Never display this to end users. |
Use type for your top-level branching, code when you need to distinguish between conditions within the same type.
LICENSE_ERROR
License validation failed. The SDK cannot operate until the license issue is resolved.
| Code | What to do |
|---|---|
|
The license key is malformed, expired, or not valid for this SDK version. Double-check the key string and confirm it has not expired in the Anyline portal. |
|
The license is not authorized for this application or bundle identifier. Verify the package name (Android) or bundle ID (iOS) matches what the license was issued for. |
|
The SDK could not verify the license with the backend. Check network connectivity, then retry |
CONFIG_ERROR
The configuration or arguments you provided are invalid. Fix the input before retrying.
| Code | What to do |
|---|---|
|
A parameter value is out of range or missing. Review the config, options, or feedback arguments. Common causes: |
NETWORK_ERROR
The device cannot reach the backend. These are transient failures that can be retried.
| Code | What to do |
|---|---|
|
The device has no network access. Prompt the user to check Wi-Fi or mobile data, then retry the operation. |
|
Frame upload to the backend failed. This is typically a connectivity issue. Ask the user to retry the scan with a stable connection. |
|
The backend did not respond within the expected time. Retry the operation. If timeouts persist, check whether the network is throttled or whether a proxy is interfering. |
SCAN_ERROR
Something went wrong during the scan lifecycle. The scan has ended and must be restarted.
| Code | What to do |
|---|---|
|
You called a scan or result method before |
|
|
|
The SDK could not create a measurement session on the backend. Confirm the SDK is initialized, the network is available, and retry. |
|
The backend could not produce a result from the uploaded frames. Ask the user to repeat the scan with steady motion and a complete pass over the tread. |
|
A scan is already in progress. Either ignore the duplicate start attempt or wait for the current scan to finish before starting another. |
|
An unexpected internal failure occurred. Log the |
|
A failure that does not match any known condition. Treat it as a generic scan failure, log the |
RESULT_ERROR
Result retrieval failed after a scan completed.
| Code | What to do |
|---|---|
|
The measurement UUID is not recognized. Verify that it came from a |
|
The backend could not return the result. Retry |
|
The heatmap could not be retrieved. |
Practical error handling example
-
Android
-
iOS
private fun handleError(error: SdkError) {
when (error.type) {
ErrorType.LICENSE_ERROR -> {
// Fatal for this session. Show a clear message and stop.
showFatalError("License issue: ${error.message}")
}
ErrorType.CONFIG_ERROR -> {
// Developer mistake. Fix the config and retry.
Log.e("TTR", "Config error: ${error.code} - ${error.message}")
showRetryableError(error.message)
}
ErrorType.NETWORK_ERROR -> {
// Transient. Prompt user to check connectivity.
showRetryableError("Network issue: ${error.message}")
}
ErrorType.SCAN_ERROR -> {
// Scan failed. Log details for support and offer retry.
Log.e("TTR", "Scan error: ${error.code} debug=${error.debug}")
showRetryableError(error.message)
}
ErrorType.RESULT_ERROR -> {
// Result retrieval failed. Retry or show the error.
showRetryableError(error.message)
}
}
}
private func handleError(_ error: SdkError) {
switch error.type {
case .licenseError:
// Fatal for this session. Show a clear message and stop.
showFatalError("License issue: \(error.message)")
case .configError:
// Developer mistake. Fix the config and retry.
print("Config error: \(error.code) - \(error.message)")
showRetryableError(error.message)
case .networkError:
// Transient. Prompt user to check connectivity.
showRetryableError("Network issue: \(error.message)")
case .scanError:
// Scan failed. Log details for support and offer retry.
print("Scan error: \(error.code) debug=\(String(describing: error.debug))")
showRetryableError(error.message)
case .resultError:
// Result retrieval failed. Retry or show the error.
showRetryableError(error.message)
default:
showRetryableError(error.message)
}
}