shack05
shack05

Reputation: 33

How to automatically log responses using Flurl v3.0.0

I'm using Flurl in integration testing and trying to configure a client to log responses (using Flurl.Http 3.0.0).

I'm using event handlers to read the response as a string and then log it. However, if the calling code uses IFlurlResponse.GetJsonAsync<> when the logging is enabled, the deserialized object is null (I imagine because the stream has already been read).

I thought it may be possible because I can see that internally Flurl tracks whether the response stream has been read (using the _streamRead and _capturedBody members).

Here's a repro, using Flurl.Http 3.0.0:

   class Program
    {
        static async Task Main(string[] args)
        {
            using (var client = new FlurlClient("https://jsonplaceholder.typicode.com/"))
            {
                var post = await client
                            .Request("posts/1")
                            .ConfigureRequest(settings => settings.AfterCallAsync = LogResponse)
                            .GetJsonAsync<Post>();
                Console.WriteLine($"Is null with logging enabled: {post is null}"); // prints True

                post = await client.Request("posts/1").GetJsonAsync<Post>();
                Console.WriteLine($"Is null with logging disabled: {post is null}"); // prints False
            }
        }

        private static async Task LogResponse(FlurlCall call)
        {
            var responseString = await call.Response.GetStringAsync();
            Console.WriteLine(responseString);
        }
    }

    public class Post
    {
        public int Id { get; set; }
        public int UserId { get; set; }
        public string Title { get; set; }
        public string Body { get; set; }
    }

Output:

{
  "userId": 1,
  "id": 1,
  "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
  "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
Is null with logging enabled: True
Is null with logging disabled: False

If I change the calling code from using GetJsonAsync<> to GetStringAsync and handle json deserialization myself then the response can be 'read' twice, but it's more verbose.

Upvotes: 3

Views: 1141

Answers (1)

Todd Menier
Todd Menier

Reputation: 39339

UPDATE: The fix has been released.


You're correct that in most cases Flurl "captures" deserialized responses so they can easily be read multiple times. But, as I think you came close to concluding, this currently only works when you're deserializing to the same type. If both the event handler and main logic were deserializing to a string, or both to a Post, this should work.

I'm not sure if I'd quite call this a bug (maybe?), but I'm definitely convinced that getting it to work as you're expecting here would be a nice enhancement and not too hard. Please open an issue and I'll look at getting this done in a future release.

Upvotes: 1

Related Questions