Hi Jaewoong, nice article, but there are a few things I don't like. I think having custom retrofit call and call adapter is a good start to have more control on results and mapping that happend inside the "network layer", but on the other hand what you do here is using the NetworkResult class directly in the UI (in that case ViewModel) and by doing that the network/repository/domain/presentation separation just goes away. Also it seems for me that onError {} and onException {} methods are kinda useless, as you can just use CoroutineExceptionHandler for that.
I think that what could be done slightly better is to have a mapping from the network/data/whatever layers exceptions to domain exceptions, so that the UI only uses what it should really know about. It would allow you to use CoroutineExceptionHandler easier and you wouldn't have to use and pass the NetworkResult class in every layer 🙂