user5045166
user5045166

Reputation:

Application_Error() not firing

I'm trying to run an ASP.NET application that logs exceptions to the database. I'm using Application_Error to catch the exception.

Before adding the connection string, just to test my code (Logger class and the code in Global.asax), I tried to log the error to windows event viewer. This works as expected.

But after adding the connection string to the Web.config file and adding the ADO.NET code, I tried to run the application. But I get the yellow screen of death :D

I don't know what is wrong with my code. I only modified the connectionStrings element in the Web.config file and added the ADO.NET code.

Here is the code.

This is the web form code in the Page_Load event. The Countries.xml file is not present and it is expected to throw an error.

DataSet dataset = new DataSet();
dataset.ReadXml(Server.MapPath("~/Countries.xml"));
GridView1.DataSource = dataset;
GridView1.DataBind();

Application_Error

Exception exception = Server.GetLastError();
if (exception != null)
{
Logger.Log(exception);
Server.ClearError();
Server.Transfer("~/Errors.aspx");
}

Web.config

<configuration>
<connectionStrings>
    <add name="DBCS" connectionString="Data Source=.;database=Sample;Integrated Security=SSPI" providerName="System.Data.SqlClient" />
  </connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.5.2" />
</system.web>
</configuration>

I tried debugging by placing a breakpoint at the Application_Error method in Global.asax, but the control never reaches to that point. The exception is triggered from the Page_Load event. There are no compilation errors in the Logger class code. Also, I don't want to use the customErrors route to solve this problem.

Thanks in advance.

This is the link to the code: https://drive.google.com/folderview?id=0B5K22Q9r50wXU0VOQmJKVHBoaDg&usp=sharing

Upvotes: 14

Views: 13820

Answers (4)

Koby Douek
Koby Douek

Reputation: 16675

For me the problem was that endResponse was set to false.

I changes from false to true and it solved the issue:

HttpContext.Current.Response.Redirect($"/e/{errorId}", true);

Upvotes: 0

HasanG
HasanG

Reputation: 13161

In my case I had error logging (sentry.io) inside this event handler and the logging algorithm caused error itself thus redirecting to error pages defined inside the web.config and I also thought it isn't firing. Make sure you use try-catch for your code inside the error handler too in order to debug the case. Ie. flush exception details as response and end the response.

Here is my error logger to sentry.io:

public static void LogException(Exception ex, bool redirect = true)
{
    if (ex != null)
    {
        if (HttpContext.Current.Request.IsLocal)
        {
            throw ex;
        }

        // ignore Response.Redirect errors
        if (ex.GetType() == typeof(ThreadAbortException))
        {
            return;
        }

        var sentryApiKey = GetAppSetting("SentryIO.ApiKey");

        if (string.IsNullOrEmpty(sentryApiKey))
        {
            throw new NullReferenceException("SentryIO.ApiKey not defined as app setting.");
        }

        var ravenClient = new RavenClient(sentryApiKey);
        ravenClient.Capture(new SentryEvent(ex));

        if (redirect)
        {
            HttpContext.Current.Response.StatusCode = 404;
            HttpContext.Current.Response.Redirect("/?500-error-logged");
        }
    }
}

As I see building in release mode or having web.config like below, doesn't prevent this event from firing.

<compilation debug="false" targetFramework="4.5.2" />
<customErrors mode="RemoteOnly" defaultRedirect="errordocs/500.htm">
    <error statusCode="403" redirect="errordocs/403.htm" />
    <error statusCode="404" redirect="errordocs/404.htm" />
</customErrors>

Upvotes: 0

jegtugado
jegtugado

Reputation: 5141

Have you enabled custom errors on the web.config?

<system.web>
    ...
    <customErrors mode="RemoteOnly" defaultRedirect="~/Errors.aspx" redirectMode="ResponseRewrite" />
    ...
</system.web>

Note that the redirect mode is 'ResponseRewrite' in-order to preserve the Server.GetLastError() exception. If you set this otherwise then Server.GetLastError() will return null.

Implementing Application_Error should be easy.. in Global.asax

protected void Application_Error(Object sender, EventArgs e)
{
    Exception ex = Server.GetLastError();
    if (ex is ThreadAbortException)
        return; // Redirects may cause this exception..
    Logger.Error(LoggerType.Global, ex, "Exception");
    Response.Redirect("unexpectederror.htm");
}

UPDATE:

A possible culprit would be the HandlerErrorAttribute registered as filter on the Global.asax.

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute()); // this line is the culprit
}

Simply comment out or remove the line and make sure you have implemented the customErrors in the system.web under web.config.

I'm not that familiar with the HandleErrorAttribute, if this resolves your issue then might as well look up its documentation.

Upvotes: 0

Win
Win

Reputation: 62260

If you have <customErrors mode="Off" /> while debugging, the code won't reach to Application_Error event because exception is displayed inside browser right away.

If you want to reach Application_Error while debugging, you want to enable custom error -

<customErrors mode="On" defaultRedirect="~/Error.aspx" />

Upvotes: 2

Related Questions