title: Elegant way of handling error using Retrofit + Kotlin Flow
body: <p>I have a favorite way of doing network request on Android (using Retrofit). It looks like this:</p>
  <pre class="lang-java prettyprint-override"><code>// NetworkApi.kt
  
  interface NetworkApi {
    @GET(&quot;users&quot;)
    suspend fun getUsers(): List&lt;User&gt;
  }
  </code></pre>
  <p>And in my ViewModel:</p>
  <pre class="lang-java prettyprint-override"><code>// MyViewModel.kt
  
  class MyViewModel(private val networkApi: NetworkApi): ViewModel() {
    val usersLiveData = flow {
      emit(networkApi.getUsers())
    }.asLiveData()
  }
  </code></pre>
  <p>Finally, in my Activity/Fragment:</p>
  <pre class="lang-java prettyprint-override"><code>//MyActivity.kt
  
  class MyActivity: AppCompatActivity() {
    private viewModel: MyViewModel by viewModels()
  
    override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)
      setContentView(R.layout.activity_main)
  
      viewModel.usersLiveData.observe(this) {
        // Update the UI here
      }
    }
  }
  </code></pre>
  <p>The reason I like this way is because it natively works with Kotlin flow, which is very easy to use, and has a lot of useful operations (flatMap, etc).</p>
  <p>However, I am not sure how to elegantly handle network errors using this method. One approach that I can think of is to use <code>Response&lt;T&gt;</code> as the return type of the network API, like this:</p>
  <pre class="lang-java prettyprint-override"><code>// NetworkApi.kt
  
  interface NetworkApi {
    @GET(&quot;users&quot;)
    suspend fun getUsers(): Response&lt;List&lt;User&gt;&gt;
  }
  </code></pre>
  <p>Then in my view model, I can have an if-else to check the <code>isSuccessful</code> of the response, and get the real result using the <code>.body()</code> API if it is successful. But it will be problematic when I do some transformation in my view model. E.g.</p>
  <pre class="lang-java prettyprint-override"><code>// MyViewModel.kt
  class MyViewModel(private val networkApi: NetworkApi): ViewModel() {
    val usersLiveData = flow {
      val response = networkApi.getUsers()
      if (response.isSuccessful) {
        emit(response.body()) // response.body() will be List&lt;User&gt;
      } else {
         // What should I do here?
      }
    }.map { // it: List&lt;User&gt;
      // transform Users to some other class
      it?.map { oneUser -&gt; OtherClass(oneUser.userName) }
    }.asLiveData()
  </code></pre>
  <p>Note the comment &quot;What should I do here?&quot;. I don't know what to do in that case. I could wrap the responseBody (in this case, a list of Users) with some &quot;status&quot; (or simply just pass through the response itself). But that means that I pretty much have to use an if-else to check the status at every step through the flow transformation chain, all the way up to the UI. If the chain is really long (e.g. I have 10 <code>map</code> or <code>flatMapConcat</code> on the chain), it is really annoying to do it in every step.</p>
  <p>What is the best way to handle network errors in this case, please?</p>