How to display Reference ID or HandlingInstanceId in <customErrors> page?

Topics: Exception Handling Application Block
Dec 23, 2008 at 6:50 PM
We are writing an ASP.NET application using .NET 3.5 with Enterprise Library 4.1. and in Application_Error() we are using ExceptionPolicy.HandleException() to handle/log errors.  In addition, we are using the <customErrors> element to display a generic error web page to the users after the error is logged.

In this generic web page, we do not want to show them the actual error message but we would like to provide them with a reference ID that they can use when they contact customer support.  I read the "Assisting Support Staff " help document and I understand that this is what the HandlingInstanceId is for but I'm a little unclear how I can access that from my generic error web page.  Can anyone provide a working example of how to do this?

BTW I thought I remembered seeing a demo that did this at VS Live 2005 in San Francisco.  I looked through my conference demo code samples but I couldn't find this one.

Thanks,
David
Dec 24, 2008 at 2:57 PM
Hi,

Have you tried following the steps that is specified in the section "Assisting Support Staff ", specifically the #6 step, because it has a example that displays the handlingInstanceId but is done inside the custom handler.


Valiant Dudan
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com
Dec 30, 2008 at 5:18 PM
Hi Valiant,

Thanks for your response.  Before my original posting I had already read the "Assisting Support Staff " article including the code sample for step #6 but this sample is a WinForms example.

Are there any examples for how to do this for a ASP.NET application?  Specifically with a Application_Error() call to ExceptionPolicy.HandleException() and using the <customErrors> element to display a generic error web page which contains the HandlingInstanceId?

Thanks,
David
Jan 5, 2009 at 3:47 AM
Edited Jan 5, 2009 at 3:49 AM
Hi,

You can try following the steps in the "Assisting Support Staff " and apply it to a ASP.NET app. In step #6 you are asked to create a custom exception handler which will display the HandlingInstanceId to the user. In the custom exception handler you can try adding the HandlingInstanceId to a session and just retrive that value upon the load of the CustomError page.

Here is a sample custom exception handler:

namespace

CustomHandler 
{
[
ConfigurationElementType(typeof(CustomHandlerData))] 
public class MyCustomExceptionHandler : IExceptionHandler
{
public MyCustomExceptionHandler(NameValueCollection ignore) 
{

 

 

}

 

#region IExceptionHandler Members

 

 

public Exception HandleException(Exception exception, Guid handlingInstanceId) 
{

 

 

HttpContext context = HttpContext.Current; 
if (context != null)
{
context.Session[
"__ASPNET_ERROR_INSTANCE_ID"] = handlingInstanceId.ToString(); 
}

 

 

return exception; 
}

 

 

#endregion

}
}


Hope this helps.


Valiant Dudan
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Jan 8, 2009 at 9:19 PM
Thanks Valiant!

Our project is not using Session state.  Do you know of another way to pass the handlingInstanceId to the Error Page?  We are using the <customErrors> element for the redirection so I don't see a way to add it to the querystring either.

David
Jan 19, 2009 at 3:35 PM
Hi David,

Sorry for the late reply. You can try it like this:

In your custom handler:

public

Exception HandleException(Exception exception, Guid handlingInstanceId)
{
exception.Data.Add("HandlingInstanceId", handlingInstanceId.ToString());
return exception;
}

On the Application_Error of the Global.asax, you can do it something like this:

 

 

void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
try
{
bool rethrow = Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionPolicy.HandleException(ex, "Replace Policy");
}
catch (Exception newEx)
{

 

}
Server.Transfer(

"Error.aspx?HID=" + ex.Data["HandlingInstanceId"].ToString());
}

And on your Error page, just access the query string.


Hope this helps.


Valiant Dudan
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

 

Feb 20, 2009 at 7:42 PM
Hi Valiant,

Thanks for your response.  In the meantime, I figured out an alternative way that allows me to continue using the <customErrors> element to display a generic error web page and add the HandlingInstanceId.

The key is to use the redirectMode="ResponseRewrite" attribute setting of the customErrors element.  "ResponseRewrite" causes a Server.Transfer() to the error page instead of Response.Redirect().  This allows me to use the HttpContext.Items collection to pass the "HandlingInstanceId" to the error page.

See the snippets below.

David

// Web.Config
<customErrors mode="RemoteOnly" defaultRedirect="CriticalError.aspx" redirectMode="ResponseRewrite" />

// Global.asax
    void Application_Error(object sender, EventArgs e)
    {
        Exception ex = Server.GetLastError();
        if (null != ex)
        {
            ExceptionPolicy.HandleException(ex, "CriticalError");
        }
    }

        Exception IExceptionHandler.HandleException(Exception exception, Guid handlingInstanceId)
        {
            if (null != HttpContext.Current)
            {
                HttpContext.Current.Items["HandlingInstanceId"] = handlingInstanceId;
            }

            return exception;
        }

public partial class CriticalError : System.Web.UI.Page
{
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        string handlingInstanceId;
        if (null == HttpContext.Current.Items["HandlingInstanceId"])
        {
            handlingInstanceId = "N/A";
        }
        else
        {
            Guid handlingInstanceIdKey = (Guid)HttpContext.Current.Items["HandlingInstanceId"];
            handlingInstanceId = handlingInstanceIdKey.ToString();
        }

        HandlingInstanceId.Text = handlingInstanceId;
    }
}

Feb 23, 2009 at 2:20 AM
Thanks for the info.

Valiant Dudan
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com
Feb 21, 2010 at 4:01 AM

Hi,

 

I have a question about HandlingInstanceId. I am logging exception in database. I want to send custom exception to users with handling instance id so that they can contact support staff.

Is there a way to do it?

<font size="2" color="#0000ff"><font size="2" color="#0000ff">

bool 

</font></font><font size="2" color="#0000ff">

 

</font>

rethrow = ExceptionPolicy.HandleException(ex, "Business Layer Policy");  // this logs exception in database

The message in log table in logging database is as follows

HandlingInstanceID: bbe507a4-0ba9-4430-a77f-6d36873d3ec3  An exception of type 'System.DivideByZeroException' occurred and was caught.  ----------------------------------------------------------------------------  02/20/2010 22:48:23  Type : System.DivideByZeroException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089  Message : Attempted to divide by zero. 

So it does have handling instance id in the message. I need to get this instance id.

 

Regards

Mac

Feb 21, 2010 at 4:01 AM

Hi,

 

I have a question about HandlingInstanceId. I am logging exception in database. I want to send custom exception to users with handling instance id so that they can contact support staff.

Is there a way to do it?

<font size="2" color="#0000ff"><font size="2" color="#0000ff">

bool 

</font></font><font size="2" color="#0000ff">

 

</font>

rethrow = ExceptionPolicy.HandleException(ex, "Business Layer Policy");  // this logs exception in database

The message in log table in logging database is as follows

HandlingInstanceID: bbe507a4-0ba9-4430-a77f-6d36873d3ec3  An exception of type 'System.DivideByZeroException' occurred and was caught.  ----------------------------------------------------------------------------  02/20/2010 22:48:23  Type : System.DivideByZeroException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089  Message : Attempted to divide by zero. 

So it does have handling instance id in the message. I need to get this instance id.

 

Regards

Mac

Feb 22, 2010 at 5:49 AM

Hi,

My idea here is you should:

  1. Extend the Logging table to add a new column that will hold the HandlingInstanceID.
  2. Modify the WriteLog stored procedure to insert the HandlingInstanceID
  3. Extend the LogEntry class and add a new property that will hold the HandlingInstanceID
  4. Create custom database trace listener that will insert the log to the database
  5. Create a custom exception handler that will use the CustomDatabaseTraceListner

 

Can you please try these steps.

Valiant Dudan
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Dec 23, 2014 at 2:49 PM
If you are using a ReplaceHandler, you can actually put the handlingInstanceID in your custom error message:
<exceptionHandling>
  <exceptionPolicies>
    <add name="ReplacingException">
      <exceptionTypes>
        <add name="Exception" type="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
          postHandlingAction="ThrowNewException">
          <exceptionHandlers>
            <add name="Replace Handler" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ReplaceHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling"
              exceptionMessage="An application error occurred and has been logged with error code: {handlingInstanceID}"
              exceptionMessageResourceName="" exceptionMessageResourceType=""
              replaceExceptionType="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
          </exceptionHandlers>
        </add>
      </exceptionTypes>
    </add>
  </exceptionPolicies>
</exceptionHandling>