`System.InvalidOperationException` when getting a `404 NOT FOUND` response from an endpoint
See original GitHub issueI’m just starting using this library to create set of microservices using the vertical slice feature approach. The endpoint under test
/// <summary>
/// Gets an appointment by its id
/// </summary>
public class Endpoint : Endpoint<AppointmentId, Browsable<AppointmentInfo>>
{
private readonly IUnitOfWorkFactory _unitOfWorkFactory;
private readonly LinkGenerator _linkGenerator;
/// <inheritdoc/>
public override void Configure()
{
Get("/appointments/{@id}", x => new { Id = x.Value });
Head("/appointments/{@id}", x => new { Id = x.Value });
AllowAnonymous();
}
/// <inheritdoc/>
public override async Task HandleAsync(AppointmentId req, CancellationToken ct)
{
using IUnitOfWork unitOfWork = _unitOfWorkFactory.NewUnitOfWork();
Option<AppointmentInfo> mayBeAppointment = await unitOfWork.Repository<Appointment>()
.SingleOrDefault(selector: appointment => new AppointmentInfo
{
Id = appointment.Id,
Subject = appointment.Subject,
Location = appointment.Location,
EndDate = appointment.EndDate,
StartDate = appointment.StartDate,
Attendees = appointment.Attendees.Select(attendee => new AttendeeInfo
{
Id = attendee.Id,
Email = attendee.Email,
Name = attendee.Name,
PhoneNumber = attendee.PhoneNumber,
}),
},
predicate: (Appointment x) => x.Id == req,
cancellationToken: ct).ConfigureAwait(false);
await mayBeAppointment.Match(
some: async appointment =>
{
Browsable<AppointmentInfo> browsable = new()
{
Resource = appointment,
Links = new[]
{
new Link
{
Href = _linkGenerator.GetUriByName(HttpContext, nameof(Endpoint), new { Id = req }),
Method = "GET",
Relations = new [] { LinkRelation.Self }.ToHashSet()
},
}
};
await SendOkAsync(browsable, ct).ConfigureAwait(false);
},
none: async () => await SendNotFoundAsync(ct).ConfigureAwait(false))
.ConfigureAwait(false);
}
}
The test basically checks that I indeed get a 404 when I hit the endpoint with an unknown id
public class EndpointShould : IClassFixture<AgendaWebApplicationFactory>
{
private readonly HttpClient _client;
private readonly ITestOutputHelper _outputHelper;
private readonly AgendaWebApplicationFactory _applicationFactory;
[Fact]
public async Task Returns_NotFound_when_Id_does_not_exist()
{
// Arrange
AppointmentId appointmentId = AppointmentId.New();
// Act
(HttpResponseMessage response, AppointmentInfo _) = await _client.GETAsync<Endpoint, AppointmentId, AppointmentInfo>(appointmentId);
// Assert
response.StatusCode.Should().Be(System.Net.HttpStatusCode.NotFound);
}
}
I get the following error as soon as I run the test
Message:
System.InvalidOperationException : Unable to deserialize the response body as [Agenda.API.Resources.v1.Appointments.AppointmentInfo]. Reason: [NotFound]
Arborescence des appels de procédure:
HttpClientExtensions.Send[TRequest,TResponse](HttpClient client, HttpMethod method, String requestUri, TRequest request, Nullable`1 isFormContent)
This seems to be due to the HttpClientExtensions.Send method which always deserializes the json for endpoints that are supposed to returns a response, no matter what the HTTP status code is.
A fix could be something like the following
if (typeof(TResponse) == Types.EmptyResponse)
return new(rsp, default);
TResponse? res;
if(CanDeserializeContent(rsp)) // <-- This method would check that there is a content to deserialize based on status code, content directly etc....
{
try
{
res = await rsp.Content.ReadFromJsonAsync<TResponse>(SerOpts.Options);
}
catch (JsonException)
{
var reason = $"[{rsp.StatusCode}] {await rsp.Content.ReadAsStringAsync()}";
throw new InvalidOperationException(
$"Unable to deserialize the response body as [{typeof(TResponse).FullName}]. Reason: {reason}");
}
}
return new(rsp, res);
}
static bool CanDeserialize(HttpResponseMessage response) => response.StatusCode != 404
I can make a PR if it’s okay for you
Issue Analytics
- State:
- Created 5 months ago
- Comments:7 (4 by maintainers)
Top Results From Across the Web
ASP.NET WebApi returns HTTP 404 instead of HTTP 401
From your description, I think it is caused by when you accessing an endpoint protected by [Authroize] , If you are not logged...
Read more >404 Not Found When accessing controller action ...
You're seeing a 404 response because the cookies handler managed by Identity is trying to redirect you to the login page, for which...
Read more >Error 404: 4 Ways to Fix It
Error 404 is a response code, meaning the server could not locate the requested content. Check this article to learn 4 steps to...
Read more >404 Not Found Error: What It Is and How to Fix It
The 404 Not Found Error is an HTTP response status code, which indicates that the requested resource could not be found. Like most...
Read more >why is 404 happened when i request action in a web API ...
when i set [Authorize] to controller , the request "/login/login",the response is "404 not found". when i delete [Authorize], ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
final release will be v6.0 for sure.
@candoumbe
decided to do a breaking change and finally sort this out: https://github.com/FastEndpoints/FastEndpoints/blob/main/Src/Library/changelog.md#breaking-changes
available in
v5.8.1.10-beta