I had been trying to set up Global Exception Handling using custom Middleware in my ASP.Net Core web API. I need to log them to a log file using Serilog. I tried a lot, but I'm not able to get it to work. I hope my friends here can help me.
My Custom Middleware :
public class ExceptionHandlingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<ExceptionHandlingMiddleware> logger;
public ExceptionHandlingMiddleware()
{
}
public ExceptionHandlingMiddleware(
RequestDelegate next,
ILogger<ExceptionHandlingMiddleware> logger)
{
_next = next ?? throw new ArgumentNullException(nameof(next));
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async Task InvokeAsync(HttpContext context)
{
if (context is null)
{
throw new ArgumentNullException(nameof(context));
}
try
{
await _next.Invoke(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex);
}
}
private async Task HandleExceptionAsync(
HttpContext context,
Exception exception)
{
try
{
int statusCode = 0;
if (context is null)
{
throw new ArgumentNullException(nameof(context));
}
if (exception is null)
{
throw new ArgumentNullException(nameof(exception));
}
this.logger.LogError(exception.ToString());
CustomApiResponse<CustomApiErrorResponse> errorResponse = null;
if (exception is MyException myExceptionInfo)
{
statusCode = myExceptionInfo.StatusCode == default ? (int)HttpStatusCode.InternalServerError : myExceptionInfo.StatusCode;
errorResponse = new CustomApiResponse<CustomApiErrorResponse>()
{
StatusCode = statusCode,
TraceId = context.TraceIdentifier,
Response = new CustomApiErrorResponse()
{
Message = myExceptionInfo.ErrorMessage,
StackTrace = myExceptionInfo.StackTrace
}
};
}
else
{
statusCode = (int)HttpStatusCode.InternalServerError;
const string message = "Unexpected error";
errorResponse = new CustomApiResponse<CustomApiErrorResponse>()
{
StatusCode = (int)HttpStatusCode.InternalServerError,
Response = new CustomApiErrorResponse()
{
Message = message,
},
TraceId = context.TraceIdentifier
};
}
var responseContent = JsonConvert.SerializeObject(errorResponse);
context.Response.ContentType = "application/json";
context.Response.StatusCode = statusCode;
await context.Response.WriteAsync(responseContent);
}
catch (Exception ex)
{
this.logger.LogError(ex.ToString());
throw;
}
}
}
Startup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
{
//app.UseExceptionHandlerMiddleware();
app.UseExceptionHandler(new ExceptionHandlerOptions
{
ExceptionHandler = new ExceptionHandlingMiddleware().InvokeAsync,
});
//app.UseExceptionHandler(options =>
//{
// options.Run(async context =>
// {
// // Exception Handling Code
// });
//}
}
Where am I going wrong? Is there anything else I need to do to get it to work? The exceptions get thrown from the code but is not caught by the middleware. Please do help me friends.
Update
I'm using GraphQL instead of REST. So there are no controllers in my app. Is that a reason for this issue?
CodePudding user response:
Try changing your startup like this:
app.UseMiddleware<ExceptionHandlingMiddleware>();
instead of
app.UseExceptionHandler(new ExceptionHandlerOptions
{
ExceptionHandler = new ExceptionHandlingMiddleware().InvokeAsync,
});
CodePudding user response:
This article will help you to learn how to do it: https://www.c-sharpcorner.com/article/implement-global-exception-handling-in-asp-net-core-application/
CodePudding user response:
Make sure your ExceptionHandlingMiddleware.cs
is in the Middleware
folder.
And use below in your configure method:-
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseMiddleware<ExceptionHandlingMiddleware>();
...
It will resolve your issue.if still not works,let me know.