Use a Resource
object to hold data or exception.
class Resource<out T> private constructor( private val data: T?, private val error: Throwable?) { val isSuccessful: Boolean get() = data != null && error == null constructor(data: T) : this(data, null) constructor(exception: Throwable) : this(null, exception) fun data(): T { if (error != null) { throw IllegalStateException("Check isSuccessful first: call error() instead.") } return data!! } fun error(): Throwable { if (data != null) { throw IllegalStateException("Check isSuccessful first: call data() instead.") } return error!! }}
NOTE: Alternative Resource object solution
Usage
val messageLiveData = MutableLiveData<Resource<String>>()
fun getMessage() { try { // fetch data val message = ... messageLiveData.value = Resource(message) } catch (e: Exception) { messageLiveData.value = Resource(e) }}
messageLiveData.observe(lifecycleOwner, Observer { event -> if (event.isSuccessful) { val message = res.data() // do something } else { val e = res.error() // handle exception }}