Home > Blockchain >  How to call FlurlHttpException.GetResponseJsonAsync when the returned type is not guaranteed?
How to call FlurlHttpException.GetResponseJsonAsync when the returned type is not guaranteed?

Time:12-01

I did not see this scenario in the online documentation, but am wondering what would happen if FlurlHttpException.GetResponseJsonAsync is called with the data type that is not actually returned. Say, the same HTTP error response code can result in ErrorA and ErrorB returned to the caller. Is there a correct way to handle multiple types supported by the same condition? For example, what happens with code ErrorA error = await ex.GetResponseJsonAsync<ErrorA>(); if the request returns ErrorB? Would it cause an exception? Or would it deserialize ErrorB into the ErrorA object (with default properties)?

I understand that the preferred way would be to make sure each HTTP response code corresponds to a single JSON object, but in our case, there is a proxy server in front of our app that can return the same HTTP error response with their own error data structure, so our code needs to be able to handle both, and I cannot easily test both scenarios (the proxy error would be very infrequent and almost impossible to simulate).

CodePudding user response:

Flurl deserializes directly from a stream, which is fast but also means there's no do-over if it fails to deserialize to the given type. I can think of 2 options:

  1. Get the string response (using GetResponseStringAsync) and deserialize that yourself. I don't believe Newtonsoft or System.Text.Json support any notion of "trying" to deserialize to a specific type without throwing, so you'd probably just have to test both types via try/catch.

  2. Create a type containing all properties from both ErrorA and ErrorB and deserialize to that. I imagine you could check for a null property or something along those lines to determine which was actually returned. If error handling is not trivial and you want to get a little more fancy, you could define 2 interfaces - IErrorA and IErrorB - that define the respective properties, declare the single error class to implement both, and define methods like HandleErrorA and HandleErrorB that take an instance of those interfaces. The calling code would still need to determine which error was returned, but the guts of the handling logic wouldn't be aware of irrelevant properties.

  • Related