global.asax中的Application_Error未捕获WebAPI中的错误

时间:2015-02-27 15:34:11

标签: c# asp.net .net asp.net-web-api error-reporting

对于我正在开发的项目,我们正在实施的一项工作是我的一些团队旧的ASP.NET和MVC项目中的代码 - Application_Error异常捕获器通过异常经验和最相关的详细信息向开发团队发送电子邮件。

以下是它的外观:

的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);
}

一个&#34;未成年人&#34;但问题是 - 当我故意让部分代码抛出异常以便测试这种机制时......

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
}

前端JavaScript会立即拦截HTTP 500请求,但是没有达到上面提到的global.asax.cs代码(我在方法的第一个执行行上设置了一个断点。)

问题:以什么方式可以获得&#34; old&#34; Application_Error处理程序发送错误电子邮件,以便我们团队的开发人员可以更轻松地调试我们的应用程序?

2 个答案:

答案 0 :(得分:58)

将您的错误处理逻辑从Application_Error抽象到自己的函数中。创建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.
    }
}

Web API中的错误不会触发Application_Error事件。但是我们可以创建一个异常过滤器并注册它来处理错误。另请参阅Global Error Handling in ASP.NET Web API 2

答案 1 :(得分:0)

就我而言,我更喜欢不使用Web.config。然后,我在Global.asax文件中创建了上面的代码:

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

那是我的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");
    }
}

那是我从@mason类复制的ErrorLogService.cs

//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
    }
}