Error Handling
Most SDK operations report failures through their listener’s onError(Throwable?). For a global view — logging SDK errors to your crash reporter, surfacing integration problems in QA builds — register a IPulsateErrorListener:
val pulsateManager = PulsateFactory.getInstance()pulsateManager.setPulsateErrorListener(object : IPulsateErrorListener { override fun onError(error: PulsateError) { Log.w("Pulsate", "type=${error.type} message=${error.message}", error.exception) // e.g. forward to Crashlytics/New Relic as a non-fatal }})PulsateError carries:
| Field | Type | Meaning |
|---|---|---|
type |
String |
Error category |
message |
String |
Human-readable description |
exception |
Exception? |
Underlying exception, when available |
Listener threading
Section titled “Listener threading”Threading differs by listener type.
Delivered on the main thread — the SDK dispatches these through their ...MainThread() default helpers (Dispatchers.Main), so the onSuccess / onError / onFeedClose / onUnauthorizedAction you override run on the main thread and may touch UI directly:
IPulsateRequestListenerIPulsateValueListener<T>IPulsateFeedListenerIPulsateUserUnauthorizedListener
No main-thread guarantee — these are invoked directly from whatever thread the SDK happens to be running on (background jobs, receivers):
IPulsateErrorListenerIPulsateBadgeUpdateListenerIPulsateGeofenceListener
For the second group, hop to the main thread (or use postValue / MutableStateFlow) before touching UI:
pulsateManager.setPulsateErrorListener(object : IPulsateErrorListener { override fun onError(error: PulsateError) { Handler(Looper.getMainLooper()).post { showErrorBanner(error.message) } }})
