问题
For a project I am working on, one of the things we're implementing is something that we have code for in some of my teams older ASP.NET and MVC projects - an Application_Error
exception catcher that dispatches an email to the development team with the exception experience and most relevant details.
Here's how it looks:
Global.asax:
protected void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
string path = "N/A";
if (sender is HttpApplication)
path = ((HttpApplication) sender).Request.Url.PathAndQuery;
string args = string.Format("<b>Path:</b> {0}", path);
// Custom code that generates an HTML-formatted exception dump
string message = Email.GenerateExceptionMessage(ex, args);
// Custom code that sends an email to the dev team.
Email.SendUnexpectedErrorMessage("Some App", message);
}
One "minor" problem, though - when I intentionally have a part of the code throw an exception in order to test this mechanism...
public static void GetMuffinsByTopping(string topping)
{
throw new Exception("Test Exception!", new Exception("Test Inner Exception!!!"));
// Actual repository code is unreachable while this test code is there
}
The front-end JavaScript is immediately intercepting an HTTP 500 request, but the global.asax.cs code noted above is not being reached (I set a breakpoint on the first executing line of the method.)
Question: In what way can I get the "old" Application_Error
handler to dispatch error emails, so that our team's developers can more easily debug our application?
回答1:
Abstract out your error handling logic from Application_Error
into its own function. Create a Web API exception filter.
//register your filter with Web API pipeline
GlobalConfiguration.Configuration.Filters.Add(new LogExceptionFilterAttribute());
//Create filter
public class LogExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
ErrorLogService.LogError(context.Exception);
}
}
//in global.asax or global.asax.cs
protected void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
ErrorLogService.LogError(ex);
}
//common service to be used for logging errors
public static class ErrorLogService
{
public static void LogError(Exception ex)
{
//Email developers, call fire department, log to database etc.
}
}
Errors from Web API do not trigger the Application_Error event. But we can create an exception filter and register it to handle the errors. Also see Global Error Handling in ASP.NET Web API 2.
回答2:
In my case, i prefer not use Web.config. Then i created code above in Global.asax file:
protected void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
//Not Found (When user digit unexisting url)
if(ex is HttpException && ((HttpException)ex).GetHttpCode() == 404)
{
HttpContextWrapper contextWrapper = new HttpContextWrapper(this.Context);
RouteData routeData = new RouteData();
routeData.Values.Add("controller", "Error");
routeData.Values.Add("action", "NotFound");
IController controller = new ErrorController();
RequestContext requestContext = new RequestContext(contextWrapper, routeData);
controller.Execute(requestContext);
Response.End();
}
else //Unhandled Errors from aplication
{
ErrorLogService.LogError(ex);
HttpContextWrapper contextWrapper = new HttpContextWrapper(this.Context);
RouteData routeData = new RouteData();
routeData.Values.Add("controller", "Error");
routeData.Values.Add("action", "Index");
IController controller = new ErrorController();
RequestContext requestContext = new RequestContext(contextWrapper, routeData);
controller.Execute(requestContext);
Response.End();
}
}
And thtat is my ErrorController.cs
public class ErrorController : Controller
{
// GET: Error
public ViewResult Index()
{
Response.StatusCode = 500;
Exception ex = Server.GetLastError();
return View("~/Views/Shared/SAAS/Error.cshtml", ex);
}
public ViewResult NotFound()
{
Response.StatusCode = 404;
return View("~/Views/Shared/SAAS/NotFound.cshtml");
}
}
And that is my ErrorLogService.cs copyed from @mason class
//common service to be used for logging errors
public static class ErrorLogService
{
public static void LogError(Exception ex)
{
//Do what you want here, save log in database, send email to police station
}
}
来源:https://stackoverflow.com/questions/28768715/application-error-in-global-asax-not-catching-errors-in-webapi