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?
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>();