{"action":"created","issue":{"url":"https://api.github.com/repos/ribot/ribot-app-android/issues/4","labels_url":"https://api.github.com/repos/ribot/ribot-app-android/issues/4/labels{/name}","comments_url":"https://api.github.com/repos/ribot/ribot-app-android/issues/4/comments","events_url":"https://api.github.com/repos/ribot/ribot-app-android/issues/4/events","html_url":"https://github.com/ribot/ribot-app-android/issues/4","id":130333026,"number":4,"title":"How do I handle HTTP errors like 401, 403, 503 etc","user":{"login":"riinav","id":3099775,"avatar_url":"https://avatars.githubusercontent.com/u/3099775?v=3","gravatar_id":"","url":"https://api.github.com/users/riinav","html_url":"https://github.com/riinav","followers_url":"https://api.github.com/users/riinav/followers","following_url":"https://api.github.com/users/riinav/following{/other_user}","gists_url":"https://api.github.com/users/riinav/gists{/gist_id}","starred_url":"https://api.github.com/users/riinav/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/riinav/subscriptions","organizations_url":"https://api.github.com/users/riinav/orgs","repos_url":"https://api.github.com/users/riinav/repos","events_url":"https://api.github.com/users/riinav/events{/privacy}","received_events_url":"https://api.github.com/users/riinav/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-02-01T11:15:08Z","updated_at":"2016-02-01T22:49:09Z","closed_at":null,"body":"First of all thanks for sharing this awesome project. **It's been a great learning resource for me esp Rx and Dagger2 parts.** I have learnt a lot form this project and also from Ribots mediums post.\r\n\r\nI am trying to figure out how do I handle 401, 403 errors gracefuly\r\n\r\nmy Retrofit service is as below\r\n```\r\n@POST(\"user/login\")\r\n    Observable<Response<UserSignIn>> signIn(@Body Register signIn);\r\n```\r\n\r\nand my DataManager is as below\r\n```\r\npublic Observable<Response<UserSignIn>> signIn(String emailId, String password) {\r\n        return mService.signIn(new SatService.Register(emailId, password))\r\n                .doOnNext(new Action1<Response<UserSignIn>>() {\r\n                    @Override\r\n                    public void call(Response<UserSignIn> response) {\r\n\r\n                        //TODO: remove sensitive debug logs\r\n                        Timber.d(\"status code: %s\", response.code());\r\n                        Timber.d(\"body: %s\", response.body());\r\n                        Timber.d(\"error body: %s\", response.errorBody());\r\n                        Timber.d(\"message: %s\", response.message());\r\n\r\n                        if(response.code() == 200) {\r\n                            UserSignIn userSignIn = response.body();\r\n\r\n                            mPreferencesHelper.putUserId(userSignIn.getUserId());\r\n                            mPreferencesHelper.putAccessToken(userSignIn.getToken());\r\n                            mPreferencesHelper.putExpires(userSignIn.getExpires());\r\n                        } else if (responce.code == 403) {\r\n                        \t// Handle this error gracefully and return some meaningful text which I can show it to the user on screen\r\n                        \t\r\n                        } ...\r\n                    }\r\n                });\r\n    }\r\n```\r\n\r\nAs you can see I am returning `Observable<Response<UserSignIn>>` from DataManager to my Presenter and in my Presenter I am again doing `if(response.code() == 200) { }` which is redundant and feels wrong to me.\r\n\r\nI think I should not pass Response to Presenter but should pass Observable<UserSignIn> \r\n\r\nI thought of using map and flatMap, but again I am stuck up with what should go in else part?\r\n```\r\nmService.signIn(new SatService.Register(emailId, password))\r\n            .map(new Func1<Response<UserSignIn>, UserSignIn>() {\r\n            @Override\r\n            public UserSignIn call(Response<UserSignIn> response) {\r\n\r\n                if(response.code() == 200) {\r\n                    return response.body();\r\n                } else {\r\n                   ** return ;** // what should I return here?\r\n                }\r\n            }\r\n        });\r\n```\r\n\r\nIs there a better way to Handle this?\r\nIs this the case for EventBus? "},"comment":{"url":"https://api.github.com/repos/ribot/ribot-app-android/issues/comments/178238828","html_url":"https://github.com/ribot/ribot-app-android/issues/4#issuecomment-178238828","issue_url":"https://api.github.com/repos/ribot/ribot-app-android/issues/4","id":178238828,"user":{"login":"ivacf","id":1452346,"avatar_url":"https://avatars.githubusercontent.com/u/1452346?v=3","gravatar_id":"","url":"https://api.github.com/users/ivacf","html_url":"https://github.com/ivacf","followers_url":"https://api.github.com/users/ivacf/followers","following_url":"https://api.github.com/users/ivacf/following{/other_user}","gists_url":"https://api.github.com/users/ivacf/gists{/gist_id}","starred_url":"https://api.github.com/users/ivacf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ivacf/subscriptions","organizations_url":"https://api.github.com/users/ivacf/orgs","repos_url":"https://api.github.com/users/ivacf/repos","events_url":"https://api.github.com/users/ivacf/events{/privacy}","received_events_url":"https://api.github.com/users/ivacf/received_events","type":"User","site_admin":false},"created_at":"2016-02-01T22:49:09Z","updated_at":"2016-02-01T22:49:09Z","body":"Hi, we usually return only the model in the Observable, as oppose to the whole Response. Like this:\r\n```java\r\n@POST(\"user/login\")\r\nObservable<UserSignIn> signIn(@Body Register signIn);\r\n```\r\nSo then, if an network error happens the observable will call `onError(Throwable error)`. With Retrofit 1 you were able to cast the Throwable to `RetrofitError` and get more information form there. However, I don't think this `RetrofitError` class is available anymore in Retrofit 2. \r\n\r\nAn option, following your example, would be to use `map` or `flatMap` in order check the http code and if it is 403 throw an specific Exception, e.g `ForbiddenException`. This exception would be received in `onError(error)` where you can check that if it's an instance of  `ForbiddenException` you need to display an specific type of message. This is the only solution I can come up with right now but there may be a better way.\r\n\r\nThis question is not really related to any bug in this project so it'd be better to post these kind of questions on [Stackoverflow](http://stackoverflow.com) or similar. Thanks.\r\n\r\n"}}