Open vsfeedback opened 1 month ago
If someone has further questions, please feel free to post them, with unit testing you need the exact error code to be returned, but as i always get 500, i can not proceed
I forgot to mention, when i try the same code in Dot Net 6 everything works just fine. and all test run.
So after much more digging, i found that Net 8 doesn't support exception middleware anymore. the new way is IExceptionHandler
So you need a Class like
using BookStore.Application.Exceptions;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System.ComponentModel.DataAnnotations;
public class GlobalExceptionHandler(ILogger<GlobalExceptionHandler> logger) : IExceptionHandler
{
public async ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken)
{
var problemDetails = new ProblemDetails();
problemDetails.Instance = httpContext.Request.Path;
if (exception is DuplicateException )
{
httpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
problemDetails.Title = "Isbn already Exists";
}
else if (exception is AuthorNotFoundException )
{
httpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
problemDetails.Title = "Author not Found";
}
else if (exception is BookNotFoundException )
{
httpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
problemDetails.Title = "Book not Found";
}
else if (exception.Message.Contains("Validation failed:"))
{
httpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
problemDetails.Detail = JsonConvert.SerializeObject(exception.Message);
problemDetails.Title = "Validation Error";
}
else
{
httpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;
problemDetails.Title = "Internal Server Error - something went wrongt";
}
logger.LogError("{ProblemDetailsTitle}", problemDetails.Title);
problemDetails.Status = httpContext.Response.StatusCode;
await httpContext.Response.WriteAsJsonAsync(problemDetails, cancellationToken).ConfigureAwait(false);
return true;
}
}
And if you use it int the startup.cs
services.AddExceptionHandler<GlobalExceptionHandler>();
services.AddProblemDetails();
But they also can be called from then program.cs with builder.services....)
This issue has been moved from a ticket on Developer Community.
I have a simpe asp core 8.0 application
with a startup.cs
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)();
{
services. AddControllers();
services. AddEndpointsApiExplorer();
services. AddSwaggerGen();
DiConfiguration.RegisterServices(services);
services. AddScoped<IBookRepository, BookRepository>();
services. AddScoped<IAuthorRepository, AuthorRepository>();
services. AddDbContext
//services. AddExceptionHandler(options =>
//{
// options. ExceptionHandlingPath = new PathString(“/Error”);
//});
services. AddIdentity<IdentityUser, IdentityRole>(options =>();
{
options. SignIn.RequireConfirmedAccount = false;
}). AddEntityFrameworkStores
services. ConfigureApplicationCookie(options =>
{
options.Cookie.Name = “auth_cookie”;
options. Cookie.SameSite = SameSiteMode.None;
options. Events.OnRedirectToLogin = context =>
{
context. Response.StatusCode = StatusCodes.Status401Unauthorized;
return Task.CompletedTask;
};
options. Events.OnRedirectToAccessDenied = context =>
{
context. Response.StatusCode = StatusCodes.Status401Unauthorized;
return Task.CompletedTask;
};
});();
services. AddScoped
}
public void Configure(IApplicationBuilder app, IHostApplicationLifetime lifetime
, ApplicationDbContext context, IdentitySeed IdentitySeed)
{
context. Database.EnsureCreated();
app. UseSwagger();
app. UseSwaggerUI();
app. UseHttpsRedirection();();
app. UseRouting();
app. UseMiddleware
app. UseExceptionHandler(“/error”);
app. UseAuthentication();
app. UseAuthorization();
app. UseEndpoints(endpoint =>
{
endpoint. MapControllerRoute(
name: “default”
, pattern: “{controller}/{action=Index}/{id}”);
});
IdentitySeed.Seed(). Wait();
}
which creates following error:
System.InvalidOperationException: "An error occurred when configuring the exception handler middleware. Either the 'ExceptionHandlingPath' or the 'ExceptionHandler' property must be set in 'UseExceptionHandler()'. Alternatively, set one of the aforementioned properties in 'Startup.ConfigureServices' as follows: 'services. AddExceptionHandler(options => { ... });' or configure to generate a 'ProblemDetails' response in 'service. AddProblemDetails()'."
addnig
services. AddExceptionHandler(options =>
{
options. ExceptionHandlingPath = new PathString(“/Error”);
});
Lets the program run as expected, but the middleware isn’t called any more, as every error ends in a 500
According to Copilot
app. UseExceptionHandler(“/error”);
should do the same as the lines in services, but the error remains poping up
my middleware has a method too catch all unknown errors
catch (Exception ex)
{
context. Response.ContentType = “application/problem+json”;
context. Response.StatusCode = StatusCodes.Status500InternalServerError;
var problemdetail = new ProblemDetails()
{
Status = StatusCodes.Status500InternalServerError,
Detail = ex. Message,
Instance = string. Empty,
Title = “Internal Server Error - something went wrongt”,
Type = string. Empty
};
var problemDetailJson = JsonConvert.SerializeObject(problemdetail);
await context. Response.WriteAsync(problemDetailJson);
}
So the question remains, even with a exception middleware, why do i need a ExceptionHandlingPath at all.
And if i need it, where can i add it without interfering in my middleware.
Original Comments
Feedback Bot on 7/18/2024, 10:02 PM:
(private comment, text removed)
Original Solutions
(no solutions)