Handling exceptions is a tricky task, specially when you start developing wep applications.
We are going to show two ways to globaly handle exceptions.
The main idea of this blog is to avoid handling exceptions on all controller actions as shown in the example bellow.
public IHttpActionResult Submit(SampleDataIn request) { try { // Do some stuff return new OkResponse(Request); } catch (Exception ex) { LogDataIn logData = new LogDataIn(); logData.Title = "SampleController/Submit"; logData.Message1 = ex.ToString(); Log.LogError(logData); return new ErrorResponse(Request); } }
Filters
We create our ExceptionFilter class that implements IExceptionFilter.
When an application exception is thrown this filter is going to execute OnException.
In this case we create an object with internal http code, a message, and the exception detail message.
This is a basic example but here you culd log exception or do whatever you want.
public class ExceptionFilter : IExceptionFilter { public void OnException(ExceptionContext context) { var result = new ObjectResult(new { code = 500, message = "Internal error ocurred. Please contact your administrator", detailedMessage = context.Exception.Message }); result.StatusCode = 500; context.Result = result; } }
Ater we create the Filter we add it to our application. This will to happen at runtime on startup.
public void ConfigureServices(IServiceCollection services) { services.AddOptions(); services.AddMvc(options => { options.Filters.Add(typeof(ExceptionFilter)); }); }
Middleware
Fortunately ASP.Net Core made developers life easy by making global exception handling available through middleware.
We are going to create a custom middleware to hanle exceptions.
Now in Startup.cs, we will add following middleware in Configure method.
app.UseExceptionHandler( builder => { builder.Run( async context => { context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; context.Response.ContentType = "application/json"; var ex = context.Features.Get<IExceptionHandlerFeature>(); if (ex != null) { var err = JsonConvert.SerializeObject(new () { Stacktrace = ex.Error.StackTrace, DetailedMessage = ex.Error.Message, Message= "Internal error ocurred. Please contact your administrator" }); await context.Response.Body.WriteAsync(Encoding.ASCII.GetBytes(err),0,err.Length).ConfigureAwait(false); } }); } );
If you want to test it just implement and action like this.
public IActionResult Get() { int j = 0; var i = 12 / j; return new ObjectResult( new { TupeSettings = this._settings, CommonSettings = this._common}); }
I hope that this was helpful for you.