exceptionblazormessageblazor-webassemblythrow

Throw exceptions on non development enviroment Blazor


I have a Blazor Hosted WebAssembly app written on .NET8, so there are three projects Client, Server and the Shared. Intercommunication happends with Web API calls. In my razor components I have the following code to throw exceptions into a pop-up modal window:

The code in any function:

if (!response.IsSuccessStatusCode)
{
    teamProcessing = false;
    var responseContent = await response.Content.ReadAsStringAsync();
    await ShowTheExceptionModal(responseContent);
}

The exception function

protected async Task ShowTheExceptionModal(string message)
{
    var options = new ModalOptions()
    {
        Size = ModalSize.Custom,
        SizeCustomClass = "bm-modal-custom"
    };
    var parameters = new ModalParameters();
    parameters.Add("message", message);
    var messageForm = modal.Show<Message_Modal>("Exception Error", parameters, options);
    var result = await messageForm.Result;
}

The above works fine when ASPNETCORE_ENVIRONMENT is 'Development' but when ASPNETCORE_ENVIRONMENT is something else, the window opens but there is no message. I think this behaviour occurs due to that exceptions might provide sensitive information. I have also read that there is a middleware when ASPNETCORE_ENVIRONMENT is not 'Development' due to this code on Program.cs of the server.

if (app.Environment.IsDevelopment())
{
    app.UseWebAssemblyDebugging();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

In my case I need to throw those exceptions and do not change the code on all functions within the application, is this possible somehow?


Solution

  • Finaly GPT did it again with the proper prompt, in addition I did some handling when the enviroment is not 'Development' to avoid major sensitive information, here is how I solved this but I would like your opinion too!

    A new ExceptionHandlingMiddleware class: using System.Net;

    namespace mynamespace.Server.Classes
    {
        public class ExceptionHandlingMiddleware
        {
            private readonly RequestDelegate _next;
            private readonly ILogger<ExceptionHandlingMiddleware> _logger;
    
            public ExceptionHandlingMiddleware(RequestDelegate next, ILogger<ExceptionHandlingMiddleware> logger)
            {
                _next = next;
                _logger = logger;
            }
    
            public async Task InvokeAsync(HttpContext context)
            {
                try
                {
                    await _next(context);
                }
                catch (Exception ex)
                {
                    //EXCEPTION LOG
                    _logger.LogError(ex, "An unhandled exception occurred.");
                    //EXCEPTION PUSH INTO WEB CLIENT
                    context.Response.ContentType = "application/json";
                    context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                    if (Parameters.enviroment == "Development")
                    {
                        //This contains sensitive information
                        //ex.ToString() deserializes the whole object
                        string exception = ex.ToString();
                        await context.Response.WriteAsync(exception);
                    }
                    else
                    {
                        //This does not contain sensitive information
                        string exception = ex.Message + Environment.NewLine + ex.StackTrace;
                        await context.Response.WriteAsync(exception);
                    }
    
                    //context.Response.Redirect("/Error"); //Redirect the exception
                    //throw; //Rethrow the exception //Carefull here it might cause unpredicted behaviour as multiple iterations can happen.
                }
            }
        }
    }
    

    A new usage into startup.cs

    app.UseMiddleware<ExceptionHandlingMiddleware>();