I'm writing my first coroutine in a production app...
# coroutines
c
I'm writing my first coroutine in a production app! It's an Android app that is using Retrofit with coroutines.
Copy code
viewModelScope.launch {
                val userProfileResponse = apiManager.client!!.getProfile()
                if (userProfileResponse.isSuccessful) {
                    _viewState.value = _viewState.value?.copy(isLoading = false, profile = userProfileResponse.body())
                } else {
                    Log.e(TAG, "Not success")
                }
        }
and it works! BUT I tried to run the app in airplane mode and it crashes. If I use a try catch it won't crash, but I'm confused by why the IDE doesn't force me to have a try/catch. Does anyone know why?
o
because it's not required by the language?
c
I could have sworn that plain old synchronous Retrofit forces you to do a try/catch and if I didn't know about it, then I probably would have been scratching my head here. Are you saying that kotlin doesn't enforce try/catch blocks? If so... I guess I should go to #getting-started because I didn't know that.
o
yea, there are no checked exceptions in kotlin
even the ones from Java/JVM languages are not required to be checked
c
👀 I had no idea. 🤯
c
@octylFractal thanks. One last question I suppose. Is there anything that helps me know which Exceptions I should catch though? Like what exceptions could the retrofit method throw? Right now I just have a general
e: Exception
that I'm catching, but I'm sure there's multiple different network error exceptions?
o
in general look at the documentation, if it's not documented then it's much more difficult.
usually all network errors can be handled as a general
IOException
unless you need more specifics
c
Thanks. I wasn't able to find anything in the readme or the github page for Retrofit + coroutines so I'll keep digging in the java docs.
If anyone finds this conversation in the future, be sure to check out https://jakewharton.com/exceptions-and-proxies-and-coroutines-oh-my/
g
This is very specific crash which is fixed
Essentially Retrofit may throw a lot of different exceptions, depending what is broken. For network it will be some child of IOException
c
This is very specific crash which is fixed
You're talking about the crash in the blog post? Not my crash... right?
g
Yes
Your crash is not specific :)
Because in offline you cannot even receive Response. Just curious, why do you use Response<T> instead of T directly?
c
I don't know if I should use Response. I actually just tweeted that at @jw I don't really know what I'm doing, but a Response type allows me to access the response code (200 or other) and I can also access response.errorBody() which is nice because my backend team sends me a completely different error body than the Type that typically comes back from the call. So basically, I use Response for error handling.
@gildor you can maybe put a PR in for retrofit to remove the crash fix if the project still has the workaround in it.
g
If you need error body, you can get it from HttpException:
Copy code
try {
  getProfile()
} catch (e: HttpException) {
  e.response().errorBody()
}
c
Interesting. I didn't know this. Still not sure what the best thing to return is. I do feel like having the Response is convenient...
g
It's error prone approach (especially when you do not use result, for example when body is null), because you have to check for success manually
Return actual result is definitely the best thing in vast majority of cases. Return Response sometimes required, but for very specific cases (you need headers of successful response or similar cases)