I believe is interesting to handle all http errors as exceptions. Not sure if is the best practice, but I gave it a try.
What I did is something like this:
public static async Task<User> LoginWithEmail (string email, string password){
try{
return await "http://myapi.com/login"
.AppendPathSegment ("login")
.SetQueryParams (new {email = email, password = password})
.WithHeader ("Accept", "application/json")
.GetJsonAsync<User> ();
}catch (FlurlHttpException e) {
return await e.Call.Response.Content.ReadAsStringAsync ()
.ContinueWith<User> ((contentAsync) => {
throw new MyApiException(JsonConvert.DeserializeObject<MyApiError> (contentAsync.Result)); });
}
}
This allows you to handle the success and error cases like this:
async void FakeLogin()
{
try{
User user = await LoginWithEmail ("fakeEmail@me.com", "fakePassword");
}
catch(MyApiException e) {
MyApiError = e.Error;
}
}
Basically
For the FlurlHttpException case, I do a continuation for ReadAsStringAsync where I declare the continuation to return a User, but inside the continuation I always throw an exception.
Additionally
You could refactor the exception handling to be as short as:
catch (FlurlHttpException e) {
return await MyApiException.FromFlurlException<User>(e);
}