ASP.Net trapping errors using web.config

Posted on 2010-09-23
Last Modified: 2012-05-10

I'm trying to trap errors in my web app.
I started here
The article suggests  at least three ways of trapping and handling errors

I want to write userID, page that caused error and Error message to the database and maybe generate an email to myself of the error( let's not worry about the last bit yet). I am using Visual Studios 2008 .

Keeping in mind the latest ASP.Net security issue I think I want to use option 3.
My question is when would I write error details to the database?
Is it in Application_Error? will Application_Error fire even though I'm using <customErrors> in web.config
Or do I write to the dB in the code-behind of the default error page?

What are best practices for this?

Question by:iftech
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 3
  • +2
LVL 21

Accepted Solution

naspinski earned 500 total points
ID: 33749189
I just use ELMAH, it is simple to set up, free and open-source and all of this will be taken care of for you.

Author Comment

ID: 33780693
Thanks for the response.

I tried implementing ELMAH with very little success.

First: I get 404 error when I try: http://localhost:58730/elmah.axd

Second:  I have a www folder which is the root folder of the app In web.config I have
<customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/error.aspx" />
 so when I try: http://localhost:58730/www/elmah.axd
I get redirected to my default error page.  

Third: Nothing is being logged into the SQL server table Elmah_error.

Here are the parts of web.config:

See nay issues? thanks.

    <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
			<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
				<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
				<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
					<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere" />
					<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
					<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
					<section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
    <sectionGroup name="elmah">
      <section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />
      <section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
      <section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
      <section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah" />
    <security allowRemoteAccess="yes" />
    <errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="Data Source=testbox\testbox08;Initial Catalog=eDENT;User ID=xxx;Password=xxxx" />

            Set compilation debug="true" to insert debugging 
            symbols into the compiled page. Because this 
            affects performance, set this value to true only 
            during development.
    <!--ASP.Net Security work around & ELMAH-->
    <customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/error.aspx" />
    <!--ASP.Net Security work around-->

      <add  verb="*" path="*.jpg" type="Thumb.ThumbnailHandler" />
      <add  verb="*" path="*.jpeg" type="Thumb.ThumbnailHandler" />
      <add  verb="*" path="*.gif" type="Thumb.ThumbnailHandler" />
			<remove verb="*" path="*.asmx" />
			<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
			<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
			<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false" />
      <add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />

			<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" />

Open in new window

LVL 15

Expert Comment

ID: 33793673
So what I would do is set customErrors mode to RemoteOnly in the web.config (this will prevent the security vulnerability). Then in the Application_Error method in the global.asax do your error handling where you'll write to the database and possibly send an email.

Things that are useful to know in Application_Error:
1. You can access the exception that was thrown with System.Web.HttpContext.Current.Server.GetLastError()
2. You can access session variables with System.Web.HttpContext.Current.Session["VarName"]
3. You can access posted data with System.Web.HttpContext.Current.Request.Form["FieldName"]
4. As long as you don't do a response.redirect or response.end in Application_Error you will not be vulnerable to the vulnerability
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

LVL 21

Expert Comment

ID: 33794466
Do you have the elmah dll in your bin or registered on your server?
LVL 21

Expert Comment

by:Craig Wagner
ID: 33794479
Setting customErrors to RemoteOnly is not the only thing you need to do to prevent the vulnerability. Unfortuantely crisco96's response leaves out a few rather important steps from what you need to do. As Phil Haack said in a recent blog post, "I’ve seen a lot of questions about [ScottGu’s] mitigations, as well as a lot of bad advice. The best advice I’ve seen is this - if you’re running an ASP.NET application, follow the advice in Scott’s blog to the letter. Better to assume your site is vulnerable than to second-guess the mitigation."

Here is a link to ScottGu's suggestions. Be sure to follow the link in this post to his first post you follow ALL the steps needed.

Back to your question...

Application_Error will fire if you have the using customErrors mode set to Off or RemoteOnly.

As long as you are using redirectMode="ResponseRewrite" on your customErrors tag, you will be able to access the exception that caused the problem from your error page using Server.GetLastError(). I believe you lose the Session variables though.

There isn't one and only one way to skin this cat. If you have information you need to get from Session or the Request you should get that information in Application_Error (it's the only place that information is available).

In one web site I've developed we have code in Application_Error that gathers everything we want to log from GetLastError and Session, writes to the log, and then allows the .NET framework (via customErrors) to redirect to the error page.

Another application I wrote I didn't need anything from Session, so rather than splitting the responsibilities between two different classes I decided to do all the logging in the error page.

One advantage of doing everything in the error page is that there are certain types of errors that won't trigger Application_Error because .NET doesn't ever forward the request to your code, it just immediately triggers an error condition. Requesting the WebResource.axd (as the vulnerability does) bypasses the Application_Error event altogether.
LVL 28

Expert Comment

ID: 33795377
It looks to me like Craig simply reiterrated what Crisco said, but first said it's a bad thing and then said that's what he does himself. He also simply gave information on the recently announced security vulnerability which the OP obviously knows about.

The biggest keys are:
1) do not return different errors based on the error type (404 vs. 500)
2) application_Error will fire assuming the request hits your web app. Otherwise the IIS error handler will fire and show the ugly yellow and red error message, this is where the customerrors tag comes in.
3) Application_error will have acces to all server, error, form, and session variables through the HttpContext
4) Application_error can be used to send emails and store to a DB. Just make sure you don't have any errors in this code itself. Use try, catch, finally where appropriate.

Author Comment

ID: 33799472
I'm a little confused now. Should I  use Application_Error to log errors  or work on getting ELMAH to work correctly to log errors?  Any one better than the other?

Thanks for the responses guys. Really appreciate it.
LVL 21

Expert Comment

by:Craig Wagner
ID: 33799641

It appears you read about half of what I wrote before repeating most of ScottGu's advice and rewording what I stated. Your points, in order:

1. This can be obtained through the link to ScottGu's blog.
2. I stated this in my last paragraph.
3. This was stated by both crisco96 and myself.
4. This is equivalent to saying, "Anywhere you write code in your app can be used to send email..." Not exactly earth-shattering information in this point.

I did not simply reiterate what crisco96 said. I elaborated on it, stating that crisco96's advice was incomplete (he stated that all you have to do to avoid the vulnerability was add mode="RemoteOnly" to customErrors, which is not true). Rather than going into detail about what you are supposed to do, I simply pointed the OP to ScottGu's blog.

I also never said it was a bad thing. I answered one of the OP's direct questions ("will Application_Error fire even though I'm using <customErrors> in web.config") which no one had done until this point. I then pointed out the differences between using the two locations (Application_Error vs. error page). I provided information to help the OP make an informed decision about what was right for his environment, because there is no "right" or "wrong" answer to this question.

I respectfully request if you're going to criticize my comments, please take the time to fully read and comprehend them first.
LVL 21

Expert Comment

by:Craig Wagner
ID: 33799746

Define "better"?

ELMAH appears to give you more out-of-the-box functionality. It is code you don't have to maintain. If you have multiple applications it's a nice way to ensure they're all handled consistently.

On the other hand, if you write the handling code yourself you can control every aspect of what it does and make it do exactly what you want it to do. If you've only got one application and will never have any more perhaps the consistency isn't a big deal.

Unfortunately those are not questions we can answer for you. You have to look at your needs, your environment, your timeline and figure out for yourself what the best course of action is. There is almost never one right answer or silver bullet ( to a problem.

Author Comment

ID: 33800403

I do have both Elmah.dll and Elmah.pdb in the bin folder. Did you notice anything with web.config that isn't right?
I think I got got all the steps.

1) Place Elmah.dll in bin folder.
2) run SQLServer.sql on the db I want to create ELMAH_Error table and stored procedures (the table and the three procedures are there)
3) edit web.config as I showed above

I decided to go with ELMAH because I several projects I need to do this for. However I do not want to do it at the server level.

LVL 21

Expert Comment

ID: 33802350
It all looks good to me.

Is this the newest version?  Maybe something has changed - have you checked with the documentation on the ELMAH site?

Author Comment

ID: 33803672
I downloaded it this week Monday to be exact, so I'm sure it's the newest version.

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An enjoyable and seamless user experience can go a long way on an eCommerce site. While a cohesive layout and engaging copy play roles in creating a positive user experience, some sites neglect aspects that seem marginal but in actuality prove very …
When crafting your “Why Us” page, there are a plethora of pitfalls to avoid. Follow these five tips, and you’ll be well on your way to creating an effective page.
The viewer will learn how to dynamically set the form action using jQuery.
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

749 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question