From d0a43cf042ab4044148db6fc5cd154a9b378dad3 Mon Sep 17 00:00:00 2001 From: Todd Date: Fri, 8 Dec 2023 16:09:31 -0600 Subject: [PATCH] get error response as dynamic with Newtonsoft missed in earlier back-ports from 3.x --- src/Flurl.Http.Newtonsoft/ExtensionMethods.cs | 15 +++++++++++---- test/Flurl.Test/Http/NewtonsoftTests.cs | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/Flurl.Http.Newtonsoft/ExtensionMethods.cs b/src/Flurl.Http.Newtonsoft/ExtensionMethods.cs index c43618d5..5c18248b 100644 --- a/src/Flurl.Http.Newtonsoft/ExtensionMethods.cs +++ b/src/Flurl.Http.Newtonsoft/ExtensionMethods.cs @@ -13,7 +13,7 @@ namespace Flurl.Http.Newtonsoft public static class ExtensionMethods { /// - /// Deserializes JSON-formatted HTTP response body to a dynamic object. + /// Deserializes a JSON-formatted HTTP response body to a dynamic object. /// /// A Task whose result is a dynamic object containing data in the response body. public static async Task GetJsonAsync(this IFlurlResponse resp) { @@ -22,7 +22,7 @@ public static async Task GetJsonAsync(this IFlurlResponse resp) { } /// - /// Deserializes JSON-formatted HTTP response body to a list of dynamic objects. + /// Deserializes a JSON-formatted HTTP response body to a list of dynamic objects. /// /// A Task whose result is a list of dynamic objects containing data in the response body. public static async Task> GetJsonListAsync(this IFlurlResponse resp) { @@ -31,7 +31,7 @@ public static async Task> GetJsonListAsync(this IFlurlResponse re } /// - /// Deserializes JSON-formatted HTTP response body to a dynamic object. Intended to chain off an async call. + /// Deserializes a JSON-formatted HTTP response body to a dynamic object. Intended to chain off an async call. /// /// A Task whose result is a dynamic object containing data in the response body. public static async Task ReceiveJson(this Task response) { @@ -41,7 +41,7 @@ public static async Task ReceiveJson(this Task response } /// - /// Deserializes JSON-formatted HTTP response body to a list of dynamic objects. Intended to chain off an async call. + /// Deserializes a JSON-formatted HTTP response body to a list of dynamic objects. Intended to chain off an async call. /// /// A Task whose result is a list of dynamic objects containing data in the response body. public static async Task> ReceiveJsonList(this Task response) { @@ -50,6 +50,13 @@ public static async Task> ReceiveJsonList(this Task + /// Deserializes a JSON-formatted error response body to a dynamic object. + /// + /// A Task whose result is a dynamic object containing data in the response body. + public static async Task GetResponseJsonAsync(this FlurlHttpException flurlException) => + (flurlException.Call?.Response == null) ? null : await flurlException.Call.Response.GetJsonAsync().ConfigureAwait(false); + /// /// Shortcut to use NewtonsoftJsonSerializer with this IFlurlClientBuilder. /// diff --git a/test/Flurl.Test/Http/NewtonsoftTests.cs b/test/Flurl.Test/Http/NewtonsoftTests.cs index b0f15696..ed940079 100644 --- a/test/Flurl.Test/Http/NewtonsoftTests.cs +++ b/test/Flurl.Test/Http/NewtonsoftTests.cs @@ -56,6 +56,24 @@ public async Task null_response_returns_null_dynamic() { var list = await resp.ReceiveJsonList(); Assert.IsNull(list); } + + [TestCase(false)] + [TestCase(true)] + public async Task can_get_error_json_untyped(bool useShortcut) { + HttpTest.RespondWithJson(new { code = 999, message = "our server crashed" }, 500); + + try { + await "http://api.com".GetStringAsync(); + } + catch (FlurlHttpException ex) { + var error = useShortcut ? // error is a dynamic this time + await ex.GetResponseJsonAsync() : + await ex.Call.Response.GetJsonAsync(); + Assert.IsNotNull(error); + Assert.AreEqual(999, error.code); + Assert.AreEqual("our server crashed", error.message); + } + } } [TestFixture, Parallelizable]