Reputation: 682
I am trying to configure a global error handler for my web app.
Configuration In the Startup.cs Configure method:
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseMiddleware<ErrorHandlerMiddleware>();
}
Middleware
public class ErrorHandlerMiddleware
{
// RequestDelegate denotes a HTTP Request completion.
private readonly RequestDelegate _next;
public ErrorHandlerMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception error)
{
var response = context.Response;
response.ContentType = "application/json";
// Creates an ErrorReponse Model out of the error message using the Fail method
var responseModel = ErrorResponse<string>.Fail(error.Message);
switch (error)
{
case ExceptionService e:
// custom application error
response.StatusCode = (int)HttpStatusCode.BadRequest;
break;
case KeyNotFoundException e:
// not found error
response.StatusCode = (int)HttpStatusCode.NotFound;
break;
default:
// unhandled error
response.StatusCode = (int)HttpStatusCode.InternalServerError;
break;
}
var result = JsonSerializer.Serialize(responseModel);
// Create a new ITempDataDictionary object
var tempData = context.RequestServices.GetRequiredService<ITempDataProvider>().LoadTempData(context);
// Add key-value pairs to the temp data dictionary
//tempData["ErrorMessage"] = "An unexpected error occurred.";
tempData["Error_Message"] = error.Message.ToString();
tempData["Error_StackTrace"] = error.StackTrace.ToString();
tempData["Error_Source"] = error.Source.ToString();
tempData["Error_TargetSite"] = error.TargetSite.ToString();
if (error.InnerException != null)
tempData["Error_InnerException"] = error.InnerException.ToString();
// Save the temp data dictionary to the HttpContext
context.RequestServices.GetRequiredService<ITempDataProvider>().SaveTempData(context, tempData);
//context.Response.Redirect(result);
context.Response.Redirect($"/Error?code={response.StatusCode}");
}
}
}
Error Controller
public class ErrorController : Controller
{
private readonly IUnitOfWork _unitOfWork;
private readonly UserManager<ApplicationUser> _userManager;
private readonly IEmailService _emailService;
private readonly AppConfiguration _appConfig;
private readonly AppMailSettings _mailSettings;
public ErrorController(IUnitOfWork unitOfWork,
UserManager<ApplicationUser> userManager,
IEmailService emailService,
IOptions<AppConfiguration> appConfig,
IOptions<AppMailSettings> mailSettings)
{
_unitOfWork = unitOfWork;
_userManager = userManager;
_emailService = emailService;
_appConfig = appConfig.Value;
_mailSettings = mailSettings.Value;
}
[AllowAnonymous]
[Route("Error")]
public async Task<IActionResult> Error(string code)
{
var Error_Message = TempData["Error_Message"];
var Error_StackTrace = TempData["Error_StackTrace"];
var Error_Source = TempData["Error_Source"] ;
var Error_TargetSite = TempData["Error_TargetSite"];
ErrorViewModel model = new ErrorViewModel();
model.ErrorMessage = "Sorry, an application error occured. Our support team has been notified.";
model.ErrorDateTime = DateTime.Now.ToString();
model.StackTrace = Error_StackTrace.ToString();
model.InnerException = TempData["Error_Message"].ToString();
model.Source = Error_Source.ToString();
model.TargetSite = Error_TargetSite.ToString();
var user = await _userManager.GetUserAsync(HttpContext.User);
var baseUrl = "http://localhost:44350";
if (user != null)
{
model.UserId = user.Id;
model.UserName = user.UserName;
model.Role = user.UserType;
var mailRequest = new MailRequest();
//mailRequest.ToAddresses = new List<string> { "[email protected]", _mailSettings.ErrorEmailAddress };
mailRequest.ToAddresses = new List<string> { "[email protected]", _mailSettings.ErrorEmailAddress };
mailRequest.Subject = "WFC Plus Error Report";
StringBuilder sb = new StringBuilder();
sb.AppendLine($"User: {model.UserName}");
// other details in string builder
sb.AppendLine($"Is Development: {model.IsDevelopment}");
mailRequest.Body = sb.ToString();
await _emailService.SendEmail(mailRequest);
}
return View(model);
}
}
Problem Invoke method of ErrorHandlerMiddleware is getting hit on startup so I know that the environment setting is correct, but exceptions that I am triggering in testing are not getting handled by the middleware.
I am not sure how to proceed.
Upvotes: 0
Views: 71