User error Flurl.Http

I am making an application where the client makes requests to the server. The server is written in the node.js file, and the client is in .NET using flurl.Http.

If the request fails on the server, it is always useful to create a custom error message. Something like that:

request.respond(500, { message: "targetid is mandatory" }); 

However, this raises a FlurlHttpException on the client side, and the JSON information in the response is lost.

How can I get this JSON information if an unsuccessful response code is received from the server?

+8
source share
4 answers

Because Flurl specializes in moving from a URL to a deserialized response body in as few keystrokes as possible, he often asks how to handle erroneous answers when the body almost always takes on a form other than successful. This is why Flurl throws out non-2XX answers by default , so you can deal with erroneous answers such as:

 try { var t = await "http://api.com".GetJsonAsync<T>(); } catch (FlurlHttpException ex) { var error = await ex.GetResponseJsonAsync<TError>(); } 

There are several options:

 ex.GetResponseStringAsync(); ex.GetResponseJsonAsync(); // returns a dynamic 
+12
source

I find it interesting to treat all HTTP errors as exceptions. Not sure if this is the best practice, but I tried.

I did 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 success and error cases, for example:

 async void FakeLogin() { try{ User user = await LoginWithEmail (" fakeEmail@me.com ", "fakePassword"); } catch(MyApiException e) { MyApiError = e.Error; } } 

Basically

In the case of FlurlHttpException, I am making a continuation for ReadAsStringAsync, where I declare a continuation to return the user, but inside the continuation I always make an exception.

Additionally

You could reorganize exception handling as short:

 catch (FlurlHttpException e) { return await MyApiException.FromFlurlException<User>(e); } 
+1
source

I solved this problem by editing the source code of Flurl. In the FlurlMessageHandler.cs file, you will find the IsErrorCondition method, which checks if an error has occurred. Whenever the response does not have a 2xx code, it is considered an error, I removed this part from the te-code, and now I manually check if the answer has succes code.

0
source

You can get the body of the failed response, although FlurlHttpException.Call , which is an instance of HttpCall , is a diagnostic object that contains (among other things) raw HttpRequestMessage and HttpResponseMessage .

Getting the body from the response requires an asynchronous call, and, unfortunately, you cannot await inside the catch , so I suggest capturing a failed call inside this catch and await catch , followed by the response body. Something like that:

 HttpCall failedCall = null; try { await url.GetAsync(); } catch (FlurlHttpException ex) { failedCall = ex.Call; } if (failedCall != null && failedCall.Response != null) { var body = await failedCall.Response.Content.ReadAsStringAsync(); // body now contains the full text of the failed response. } 

While Flurl outperforms you from the base URL to the POCO response with minimal noise, it admittedly gets louder when you need to deal with the body of the failed response. I opened a note to myself to find out if I can come up with some shortcuts here. Feel free to comment on any ideas you may have.

0
source

Source: https://habr.com/ru/post/980246/


All Articles