Error Handling Patterns
These examples show how to handle the three most common failure points in an SDK integration: initialization, route calculation, and place data retrieval. Each surface has a distinct set of error types and HTTP status codes.
SDK Initialization Errors
LzSdkManager.initialize throws LazarilloMapsError when the provided API key is invalid or the initialization sequence fails. Catch this at startup and present a user-friendly message rather than letting the app crash.
Best practice: Call initialize once in Application.onCreate so that map fragments and activities can assume the SDK is ready. If initialization fails, record the error and surface a non-fatal recovery screen.
try {
LzSdkManager.initialize(
context = applicationContext,
apiKey = apiKey,
targetParentPlaceId = placeId
)
} catch (e: LazarilloMapsError) {
// Invalid API key or initialization failure
Log.e("SDK", "Initialization failed: ${e.message}")
showUserFriendlyError("Unable to load map service")
}Route Calculation Errors
getRoute can fail at the network level (caught as an exception) or at the API level (a non-2xx HTTP response). Check both. The most actionable HTTP codes are 404 (location not found) and 401 (authentication failure). An empty but successful response means the API found both endpoints but could not build a path between them.
try {
val response = LzSdkManager.getRoute(
initialLocation = start,
finalLocation = destination
)
when {
response.isSuccessful -> {
val routes = response.body()
if (routes.isNullOrEmpty()) {
showMessage("No route found between these locations")
} else {
displayRoute(routes.first())
}
}
response.code() == 404 -> {
showMessage("One or both locations not found")
}
response.code() == 401 -> {
showMessage("API key is invalid or expired")
}
else -> {
showMessage("Route calculation failed (code ${response.code()})")
}
}
} catch (e: IllegalStateException) {
showMessage("SDK not initialized. Please restart the app.")
} catch (e: IllegalArgumentException) {
showMessage("Invalid location data: ${e.message}")
} catch (e: Exception) {
showMessage("Unexpected error: ${e.message}")
}Place Data Errors
getPlace follows the same response pattern as route requests. A 404 response means the place ID does not exist in the configured venue. Log these at the warning level because they often indicate a stale or incorrect place ID in your application data, not a runtime failure.
try {
val response = LzSdkManager.getPlace("place-123")
if (response.isSuccessful) {
val place = response.body()
// Use place data
} else {
// Place not found or API error
Log.w("SDK", "Place not found: ${response.code()}")
}
} catch (e: IllegalStateException) {
Log.e("SDK", "SDK not initialized")
}Common Pitfalls
Calling SDK methods before initialize: Every SDK method that contacts the network or reads cached data will throw IllegalStateException if initialize has not been called. Ensure initialization completes before any fragment or activity attempts to use the SDK.
Not checking isSuccessful before reading body(): Retrofit’s response.body() returns null for error responses. Always gate body() access behind an isSuccessful check or the response code.
Swallowing CancellationException: If you catch a broad Exception inside a coroutine, re-throw CancellationException so structured concurrency can cancel the coroutine correctly:
} catch (e: CancellationException) {
throw e // Do not swallow cancellation
} catch (e: Exception) {
showMessage("Unexpected error: ${e.message}")
}Related Examples
- Route Calculation and Display - Full route request flow with error handling in context
- Indoor Navigation - Handling errors during an active navigation session
- Complete Navigation Flow - End-to-end example showing where each error pattern applies