Some people like to think they never do it. I'll be the first to admit I write my share -and get pretty frustrated at times :)
At a minimum, you should configure a default static page to cover any unhandled exceptions. So in web.config:
<system.web>
<customErrors defaultRedirect='/PATH_TO_ERRORPAGE' />
</system.web>
If you're developing on localhost, your clients won't be confused by the volumous error messages, only you will.
If you want specific custom error pages based on IIS's return codes, map a page to each code, overriding what's built into IIS by default:
<system.web>
<customErrors>
<error statusCode='404' redirect='PATH_TO_404_ERRORPAGE/' />
<error statusCode='500' redirect='PATH_TO_500_ERRORPAGE' />
</customErrors>
</system.web>
Or even better, set up a global handler in global.asax that logs unhandled exceptions. For demonstration purposes we're using the Exception.Data property, new to the 2.0 Framework. It allows you to add additional information via an IDictionary:
protected void Application_Error(object sender, EventArgs e) {
try {
Exception exc = HttpContext.Current.Server.GetLastError();
exc.Data["msg"] = "[" + exc.Message + "]";
exc.Data["stack"] = exc.StackTrace;
YOUR_ERROR_LOGGING_METHOD(HttpContext.Current, exc);
}
catch {
// couldn't log error, send an email
mail_error(exc);
}
}
YOUR_ERROR_LOGGING_METHOD() logs details in a database/event log. For example, to log Exceptions to a SQL Server database:
public static void YOUR_ERROR_LOGGING_METHOD(HttpContext hc, Exception e) {
try {
HttpRequest h = hc.Request;
// get client browser details
string browser = String.Format("[{0}] [{1}] [{2}]",
h.Browser.Browser, h.Browser.Version, h.Browser.Platform
);
IPAddress ip;
string error_msg = e.Data != null && e.Data.Keys.Count != 0
? get_edata(e)
: e.Message + e.StackTrace;
// verify we have a valid IP address
if ( IPAddress.TryParse(h.UserHostAddress, out ip)
// trivial to fake client's browser string
&& browser.Length <= 100
&& error_msg.Length <= 500
)
{
using (SqlConnection c = new SqlConnection(CS)) {
using (SqlCommand cmd = new SqlCommand("exc_sp", c)) {
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("message", SqlDbType.VarChar, 500));
cmd.Parameters.Add(new SqlParameter("ip", SqlDbType.VarChar, 15));
cmd.Parameters.Add(new SqlParameter("browser", SqlDbType.VarChar, 100));
cmd.Parameters[0].Value = error_msg;
cmd.Parameters[1].Value = ip.ToString();
cmd.Parameters[2].Value = browser;
c.Open();
cmd.ExecuteNonQuery();
}
}
}
}
catch (Exception exc) {
// couldn't log error, send an email
mail_error(exc);
}
}
Assuming you've setup web.config, all unhandled exceptions will be logged. To log exceptions in your Page code-behind:
try {
// your code here
}
catch (Exception e) {
// set up e.Data key/value pairs first
CLASSNAME.YOUR_ERROR_LOGGING_METHOD(this.Context, e);
// rest of application logic
}
And your (simple logging) SQL looks like:
create table ERROR_LOGGING_TABLE (
etime datetime NOT NULL DEFAULT getdate(),
message varchar(500) NOT NULL,
ip varchar(15) NOT NULL,
browser varchar(100) NOT NULL
);
create index INDEX_NAME on ERROR_LOGGING_TABLE (etime);
create procedure EXCEPTION_LOG_SP
@message varchar(500),
@ip varchar(15),
@browser varchar(100)
AS
SET NOCOUNT ON
insert into ERROR_LOGGING_TABLE
(message,ip,browser) VALUES(@message,@ip,@browser)
Links