Skip to main content

Handle and Log Server-Side Errors in ASP.NET Core

  • 3 minutes to read

The ASP.NET Core Dashboard allows you to catch exceptions using a custom exception filter.

View Example: ASP.NET Core Dashboard - How to handle errors

Catch All Unhandled Exceptions

You can register a custom exception filter globally to catch all the unhandled exceptions. In this case, the exception filter catches unhandled exceptions from all the controllers and actions.

In your ASP.NET Core project, create the CustomExceptionFilter class that implements the IExceptionFilter interface to use a custom filter:

using Microsoft.AspNetCore.Mvc.Filters;

//...

public class CustomExceptionFilter : IExceptionFilter {
    // ...
}

Configure an exception filter:

  • Define CustomExceptionFilter to save the actual exception and information about the issue’s cause into a text file.
  • You can use the built-in ASP.NET Core logger to log errors.
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Hosting;
using System.IO;
using System.Text;
using DevExpress.DashboardCommon;

// ...

public class CustomExceptionFilter : IExceptionFilter {
    IWebHostEnvironment Env;
    public CustomExceptionFilter(IWebHostEnvironment environment) {
        Env = environment;
    }

    public void OnException(ExceptionContext context) {
        AddToLog(context.Exception, Path.Combine(Env.ContentRootPath, "Data", "Error.log"));
    }

    public static void AddToLog(Exception exception, string path) {
        StringBuilder sb = new StringBuilder();
        sb.AppendLine(DateTime.Now.ToLocalTime().ToString("F"));
        GetExceptionInfo(exception, sb);
        sb.AppendLine("------------------------------------------------------------" + Environment.NewLine);
        File.AppendAllText(path, sb.ToString());
    }

    private static void GetExceptionInfo(Exception exception, StringBuilder sb) {
        sb.AppendLine(exception.GetType().ToString());
        sb.AppendLine(exception.Message);
        sb.AppendLine("Stack Trace: ");
        sb.AppendLine(exception.StackTrace);
        if (exception is DashboardDataLoadingException) {
            foreach (var dataLoadingError in ((DashboardDataLoadingException)exception).Errors) {
                sb.AppendLine("InnerException: ");
                GetExceptionInfo(dataLoadingError.InnerException, sb);
            }
        }
        if (exception.InnerException != null) {
            sb.AppendLine("InnerException: ");
            GetExceptionInfo(exception.InnerException, sb);
        }
    }
}

Add the created CustomExceptionFilter to the MvcOptions.Filters collection:

var builder = WebApplication.CreateBuilder(args);
// ...
builder.Services.AddControllersWithViews(options => { options.Filters.Add(typeof(CustomExceptionFilter)); });


builder.Services.AddScoped<DashboardConfigurator>((IServiceProvider serviceProvider) => {
    DashboardConfigurator configurator = new DashboardConfigurator();
// ...
});
// ...

app.Run();

Catch the Web Dashboard’s Unhandled Exceptions

Create a custom dashboard controller (a DashboardController descendant) and provide a custom exception filter to log the Web Dashboard’s exceptions separately:

Create a Dashboard controller descendant and attach the exception filter:

using Microsoft.AspNetCore.Mvc;

// ...

[TypeFilter(typeof(CustomExceptionFilter))]
public class MyDashboardController : DashboardController {
    public MyDashboardController(DashboardConfigurator configurator) : base(configurator) { }
}

Add a routing to a custom controller:

app.MapDashboardRoute("dashboardControl", "MyDashboard");

Pass the created controller’s name as the DashboardBuilder.ControllerName method’s parameter:

<div style="position: absolute; left:0;top:0;right:0;bottom:0;">
    @(Html.DevExpress().Dashboard("clientDashboardControl1")
    .Width("100%")
    .Height("100%")
    .ControllerName("MyDashboard")
    )
</div>

In result the native ASP.NET Core logger system catches all exceptions occurred in the Web Dashboard’s code.

Note

If you set the ExceptionContext.ExceptionHandled property to true, a custom exception filter starts to handle all the application’s exceptions. In this case, the built-in the Web Dashboard’s exception handling mechanism can work incorrectly and display common error text without specific details.

Catch Connection Errors

Use the DashboardConfigurator.ConnectionError event to catch and log connection errors. The ConnectionError event is fired when the current connection parameters do not allow you to connect to a data store (for instance, the database is inaccessible).

Use the created CustomExceptionFilter.AddToLog method in the event handler to write exception details to a text file:

// ...
IFileProvider? fileProvider = builder.Environment.ContentRootFileProvider;
IConfiguration? configuration = builder.Configuration;
// ...
builder.Services.AddScoped<DashboardConfigurator>((IServiceProvider serviceProvider) => {
    DashboardConfigurator configurator = new DashboardConfigurator();


    // ...
    configurator.ConnectionError += (s, e) => {
        CustomExceptionFilter.AddToLog(
        e.Exception,
            Path.Combine(builder.Environment.ContentRootPath, "Data", "Error.log"));
    };
    return configurator;
});

// ...

Use the DashboardDataLoadingException to indicate exceptions that occur during loading data to a data source.