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:

FieldTypeMeaning
typeStringError category
messageStringHuman-readable description
exceptionException?Underlying exception, when available

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:

  • IPulsateRequestListener
  • IPulsateValueListener<T>
  • IPulsateFeedListener
  • IPulsateUserUnauthorizedListener

No main-thread guarantee — these are invoked directly from whatever thread the SDK happens to be running on (background jobs, receivers):

  • IPulsateErrorListener
  • IPulsateBadgeUpdateListener
  • IPulsateGeofenceListener

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) }
    }
})