From 397ada2350d85006f186031d4d06e19be6898b47 Mon Sep 17 00:00:00 2001 From: Douglas K Smith <97787672+DouglasKSmith@users.noreply.github.com> Date: Sat, 15 Jan 2022 13:03:27 +0100 Subject: [PATCH 1/2] Fix parenthesis bug in IsApiResponse expression, which caused IApiResponse-returning methods to throw ApiException on error, rather than assigning the exception to IApiResponse.Error --- Refit.Tests/ResponseTests.cs | 23 +++++++++++++++++++++++ Refit/RestMethodInfo.cs | 6 +++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/Refit.Tests/ResponseTests.cs b/Refit.Tests/ResponseTests.cs index fa0ad240b..85ea11c82 100644 --- a/Refit.Tests/ResponseTests.cs +++ b/Refit.Tests/ResponseTests.cs @@ -51,6 +51,9 @@ public interface IMyAliasService [Get("/GetApiResponseTestObject")] Task> GetApiResponseTestObject(); + + [Get("/GetIApiResponse")] + Task GetIApiResponse(); } [Fact] @@ -250,6 +253,26 @@ public async Task BadRequestWithEmptyContent_ShouldReturnApiResponse() Assert.Equal("Hello world", apiResponse.Error.Content); } + [Fact] + public async Task BadRequestWithStringContent_ShouldReturnIApiResponse() + { + var expectedResponse = new HttpResponseMessage(HttpStatusCode.BadRequest) + { + Content = new StringContent("Hello world") + }; + expectedResponse.Content.Headers.Clear(); + + mockHandler.Expect(HttpMethod.Get, $"http://api/{nameof(fixture.GetIApiResponse)}") + .Respond(req => expectedResponse); + + var apiResponse = await fixture.GetIApiResponse(); + + Assert.NotNull(apiResponse); + Assert.NotNull(apiResponse.Error); + Assert.NotNull(apiResponse.Error.Content); + Assert.Equal("Hello world", apiResponse.Error.Content); + } + [Fact] public async Task ValidationApiException_HydratesBaseContent() { diff --git a/Refit/RestMethodInfo.cs b/Refit/RestMethodInfo.cs index f7e764b36..46d8abfa5 100644 --- a/Refit/RestMethodInfo.cs +++ b/Refit/RestMethodInfo.cs @@ -126,9 +126,9 @@ public RestMethodInfo(Type targetInterface, MethodInfo methodInfo, RefitSettings CancellationToken = ctParams.FirstOrDefault(); IsApiResponse = ReturnResultType!.GetTypeInfo().IsGenericType && - (ReturnResultType!.GetGenericTypeDefinition() == typeof(ApiResponse<>) - || ReturnResultType.GetGenericTypeDefinition() == typeof(IApiResponse<>) - || ReturnResultType == typeof(IApiResponse)); + (ReturnResultType!.GetGenericTypeDefinition() == typeof(ApiResponse<>) + || ReturnResultType.GetGenericTypeDefinition() == typeof(IApiResponse<>)) + || ReturnResultType == typeof(IApiResponse); } private ISet BuildHeaderCollectionParameterMap(List parameterList) From f1b304b96eeab61cf5c3cff229bec5cfdf03433e Mon Sep 17 00:00:00 2001 From: Douglas K Smith <97787672+DouglasKSmith@users.noreply.github.com> Date: Sat, 15 Jan 2022 13:36:13 +0100 Subject: [PATCH 2/2] Update documentation --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6b13295d1..9e3f00b8c 100644 --- a/README.md +++ b/README.md @@ -1135,10 +1135,10 @@ public class HomeController : Controller ``` ### Handling exceptions -Refit has different exception handling behavior depending on if your Refit interface methods return `Task` or if they return `Task>`. +Refit has different exception handling behavior depending on if your Refit interface methods return `Task` or if they return `Task`, `Task>`, or `Task>`. -#### When returning `Task>` -Refit traps any `ApiException` raised by the `ExceptionFactory` when processing the response and any errors that occur when attempting to deserialize the response to `Task>` and populates the exception into the `Error` property on `ApiResponse` without throwing the exception. +#### When returning `Task`, `Task>`, or `Task>` +Refit traps any `ApiException` raised by the `ExceptionFactory` when processing the response, and any errors that occur when attempting to deserialize the response to `ApiResponse`, and populates the exception into the `Error` property on `ApiResponse` without throwing the exception. You can then decide what to do like so: