Global Error Handler – C#.NET example

August 3rd, 2009

This is the same as the VB.NET global error handler example, but using C#

Global.asax

<%@ Application Language="C#" %>

<script RunAt="server">

    void Application_Start(object sender, EventArgs e)
    {
        // Code that runs on application startup

    }
   
    void Application_End(object sender, EventArgs e)
    {
        //  Code that runs on application shutdown

    }
       
    void Application_Error(object sender, EventArgs e)
    {
        // Code that runs when an unhandled error occurs
       
        HttpContext ctx = HttpContext.Current;
        Exception exception = ctx.Server.GetLastError ();
       
        // do not redirect for 404
        if (exception.GetType().FullName == "System.Web.HttpException")
        {
            HttpException exHttp = (HttpException)exception;
            if (exHttp.GetHttpCode() == 404) throw exHttp;
        }
       
        ctx.Items["LastError"] = exception;
        ctx.Server.ClearError ();
        ctx.Server.Transfer("ErrorHandler.aspx");
       
    }

    void Session_Start(object sender, EventArgs e)
    {
        // Code that runs when a new session is started

    }

    void Session_End(object sender, EventArgs e)
    {
        // Code that runs when a session ends.
        // Note: The Session_End event is raised only when the sessionstate mode
        // is set to InProc in the Web.config file. If session mode is set to StateServer
        // or SQLServer, the event is not raised.

    }
      
</script>

ErrorHandler.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ErrorHandler.aspx.cs" Inherits="ErrorHandler" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "<a href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd</a>">

<html xmlns="<a href="http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</a>" >
<head runat="server">
    <title><%= ConfigurationManager.AppSettings["ApplicationName"] %> -- Error Page</title>
    <link href="ReportsStyle.css" type="text/css" rel="Stylesheet" />
</head>
<body>
    <form id="form1" runat="server">
    <asp:Panel ID="panel1" runat="server">
    <h2>An error occurred.</h2>
    <p><asp:Label ID="lblUserMsg" runat="server" /></p>
    <hr />
    <p><asp:Label ID="lblErrType" runat="server" Text="<b>Type:</b> " /></p>
    <p><asp:Label ID="lblErrMsg" runat="server" text="<b>Message:</b> " /></p>
    <p><asp:Label ID="lblErrDetail" runat="server" text="<b>Detail:</b> " /></p>
    <p><asp:Label ID="lblTrace" runat="server" Text="<b>Trace:</b> " /></p>
    <p><asp:Label ID="lblErrSrc" runat="server" Text="<b>Source:</b> " /></p>
    </asp:Panel>
    </form>
</body>
</html>

Code behind

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class ErrorHandler : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        /* application_onerror redirects here; if there is any compilation error,
         * you get an infinite loop.
         * SO BE CAREFUL CHANGING THIS PAGE
         */
        Exception lastException, baseException;
        try
        {
            lastException = (Exception)Context.Items["LastError"];
            string detail = (string)Context.Items["ErrorDetail"];
            if (lastException != null)
            {
                baseException = lastException.GetBaseException();
                lblErrType.Text += baseException.GetType().ToString();
                lblErrMsg.Text += baseException.Message;
                if (detail != null) lblErrDetail.Text += detail;
                lblTrace.Text += baseException.StackTrace;
                lblErrSrc.Text += baseException.Source;

            }
            else
            {
                lblErrType.Text += "Not available";
                lblErrMsg.Text += "Not available";
                lblTrace.Text += "Not available";
                lblErrSrc.Text += "Not available";
            }
        }
        catch (Exception exception)
        {
            //mostly this is here in case we did something stupid in that try block up there.
            lblErrMsg.Text = "Error Message: " + exception.Message;
            lblTrace.Text = "Stack Trace: " + exception.StackTrace;
            lblErrSrc.Text = "Error Source: " + exception.Source;
        }
    }
}

It has the same caveats I mentioned in the VB post. Precompile it, or you may find yourself in an endless loop.

Happy coding!

Global Error Handler – VB.NET example

August 3rd, 2009

This little example just catches all unhandled exceptions and forwards them to a page, ErrorHandler.aspx, which then displays things a little prettier.

Global.asax.vb

Imports System.Web.SessionState

Public Class Global_asax
    Inherits System.Web.HttpApplication

    Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
        ' Fires when the application is started
    End Sub

    Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
        ' Fires when the session is started
    End Sub

    Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
        ' Fires at the beginning of each request
    End Sub

    Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As EventArgs)
        ' Fires upon attempting to authenticate the use
    End Sub

    Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
        ' Fires when an error occurs
        Dim ctx As HttpContext = HttpContext.Current
        Dim oException As Exception = ctx.Server.GetLastError()
        ' do not redirect for 404
        If oException.GetType().FullName = "System.Web.HttpException" Then
            Dim exHttp As HttpException = DirectCast(oException, HttpException)
            If exHttp.GetHttpCode() = 404 Then
                Throw exHttp
            End If
        End If

        ctx.Items("LastError") = oException
        ctx.Server.ClearError()
        ctx.Server.Transfer("ErrorHandler.aspx")

    End Sub

    Sub Session_End(ByVal sender As Object, ByVal e As EventArgs)
        ' Fires when the session ends
    End Sub

    Sub Application_End(ByVal sender As Object, ByVal e As EventArgs)
        ' Fires when the application ends
    End Sub

End Class

ErrorHandler.aspx


    <form id="form1" runat="server">
    <div>
    <asp:Panel ID="panel1" runat="server">
    <h2>An error occurred.</h2>
    <p><asp:Label ID="lblUserMsg" runat="server" /></p>
    <hr />
    <p><asp:Label ID="lblErrType" runat="server" Text="<b>Type:</b> " /></p>
    <p><asp:Label ID="lblErrMsg" runat="server" text="<b>Message:</b> " /></p>
    <p><asp:Label ID="lblErrDetail" runat="server" text="<b>Detail:</b> " /></p>
    <p><asp:Label ID="lblTrace" runat="server" Text="<b>Trace:</b> " /></p>
    <p><asp:Label ID="lblErrSrc" runat="server" Text="<b>Source:</b> " /></p>
    </asp:Panel>
    </div>
    </form>

ErrorHandler.aspx.vb


    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        ' application_onerror redirects here; if there is any compilation error,
        ' you get an infinite loop.
        ' SO BE CAREFUL CHANGING THIS PAGE
        '
        Dim lastException, baseException As Exception
        Try
            lastException = DirectCast(Context.Items("LastError"), Exception)

            Dim detail As String = DirectCast(Context.Items("ErrorDetail"), String)
            If Not lastException Is Nothing Then
                baseException = lastException.GetBaseException()
                lblErrType.Text += baseException.GetType().ToString()
                lblErrMsg.Text += baseException.Message
                If Not String.IsNullOrEmpty(detail) Then
                    lblErrDetail.Text += detail
                End If
                lblTrace.Text += baseException.StackTrace
                lblErrSrc.Text += baseException.Source
            Else
                lblErrType.Text += "Not available"
                lblErrMsg.Text += "Not available"
                lblTrace.Text += "Not available"
                lblErrSrc.Text += "Not available"
            End If
        Catch oException As Exception
            'mostly this is here in case we did something stupid in that try block up there.
            lblErrMsg.Text = "Error Message: " + oException.Message
            lblTrace.Text = "Stack Trace: " + oException.StackTrace
            lblErrSrc.Text = "Error Source: " + oException.Source
        End Try

    End Sub

Note that this would catch all exceptions, including compile errors, so be sure to precompile before deploying! If you don’t, and there’s a compile error on the error page itself, you have fun with an endless loop. 

For more information, see How to: Handle Application-Level Errors