I am developing an Android App.
I am using Retrofit2 and Coroutine to fetch some data from my Rest API.
When there is an exception thrown in my Rest API, it returns exception code and exception message with HTTP status = 4xx or 5xx as per the screenshot below
If the response is an exception, then I map the exceptionCode and exceptionMessage to the response in my Android app as per the code below.
val exceptionBody = Gson().fromJson(response.errorBody()?.string(), ExceptionResponse::class.java)
This is ExceptionResponse class
data class ExceptionResponse(
val exceptionCode: String,
val exceptionMessage: String
)
Here is a problem. When I do response.errorBody()?.string(), Android Studio gives me a warning saying "inappropriate blocking method call"
Here is my repository calling the network call
override fun fetchData() {
CoroutineScope(Dispatchers.IO).launch {
val fetchedData = myRemoteDataSource.fetchData()
}
}
Here is MyRemoteDataSource class
class MyRemoteDataSourceImpl(
private val myAPIService: MyAPIService
): BaseRemoteDataSource(), MyRemoteDataSource {
override suspend fun fetchData(): Resource<List<Data>> {
return getResult {
myAPIService.fetchData()
}
}
}
And here is my BaseRemoteDataSource class which has the getResult() where errorBody.string is called
As you can see in the screenshot above, the only coroutine that does not give me the warning is the last one
GlobalScope.launch(Dispatchers.IO) {
Gson().fromJson(response.errorBody()?.string(), ExceptionResponse::class.java)
}
So I have a few questions about this warning and coroutineScope
- Why the last one does not give me the warning but every other coroutine scopes?
GlobalScope.launch(Dispatchers.IO) {
Gson().fromJson(response.errorBody()?.string(), ExceptionResponse::class.java)
}
- It seems like I need structured concurrency because I need to parse JSON and return it. If I
CoroutineScopeorGlobalScopethen I will return null unless I usescope.join. Then shouldn't I use coroutineScope() which is using the parent/caller's coroutine scope for structured concurrency?
- It looks like response.errorBody()?.string() is parsing JSON which is supposed to be in Dispatchers.Default, is not it? Just for your reference, I include the source code for
string()
public final String string() throws IOException {
try (BufferedSource source = source()) {
Charset charset = Util.bomAwareCharset(source, charset());
return source.readString(charset);
}
}
- Is it fine to use the last one because then I am creating GlobalScope in CoroutineScope.
- does withContext() use caller's coroutine scope just like coroutineScope() or does it create a new scope with different Dispatchers?
Sorry for dumping questios at once but they are all related. Thank you Guys!!!

