In the Application_Error method in Global.asax I am trying to retrieve a value from session state.
I am able to access session state as long as I throw the exception. EG:
thow new Exception("Test exception");
However if it is an unhandled exception, i get the following error when trying to access session state: "Session state is not available in this context.".
Why the differences in behavior, is there a work around?
Thanks.
I hate ASP.NET sometimes...
So generating an error using:
Response.Redirect("thispagedoesnotexist.aspx", false);
The above line will redirect to Application_Error with session state not available
However
throw new Exception("test");
The above line will redirect to Application_Error with session state AVAILABLE
So instead of doing this all in Application_Error, in one spot, I will have to use try/catches through out my code to catch errors. Then gather data from session, log and email error details, then finally redirect to friendly error page. Lots of extra code..
Conclusion: Application_Error is worthless.
I think you are trying to access the session through HttpContext.Current.Session. I believe the difference in behavior is that in the unhanded exception handler, the request has gone into "Failsafe" mode and the page lifecycle (including loading and disposing the session) has finished.
Check out this page on the lifecycle for more info
Related
I want to handle all uncaught exceptions in my ASP.NET application. I want to display a custom UI to the user, but NOT redirect them (so the URL would be the original URL which produced the exception). I also have ELMAH which is configured by the end-user (well, end-administrator really, but not me). Elmah attaches a handler to the Application.Error event and does it's logging there.
I now have two possible places to handle the error and generate the output Application_Error and Application_EndRequest. The logical place would be Application_Error, but that has two problems:
If I don't remove the exception with ClearError(), ASP.NET will replace my output with it's own default output.
But if I do remove it with ClearError(), then ELMAH might not get the exception because the event handler execution order is undefined.
I checked that the error still persists in Application_EndRequest so I could do it there, but that feels kinda.... wrong. Can I get into trouble by doing this?
I am using .net framework 4.0, plain asp.net and working with webform. Currently I having a base class to handle all parameter passing and redirect. I wonder is it possible to write a base class to handle nullRefeerenceException from all pages in once, lets say redirect end user to somewhere or display particular error message.
Scenario: For example, some pages must come along with parameter, if no parameter captured, I would like to redirect them to somewhere.
You can try to control the ProcessRequest. You need to test it to see if can do the work you ask for, but this is a good point to capture all errors of your page.
public override void ProcessRequest(HttpContext context)
{
try
{
base.ProcessRequest(context);
}
catch (Exception x)
{
// handle here your error from the page...
}
}
Some more notes
I was use this code on one critical page, but I do not use it for all my page. Even tho can capture the errors, some times you can not do nothing else here other than throw again the final error, so end up that is better to log your unknown and unhandled errors from globa.asax Application_Error, and on page make sure that you use try/catch to handle them where they happens.
After some think maybe is not good practice to use it. Good practice is to use try/catch in the place that you may have throws and not a general one like that.
Last
You also get throw error here when the user close the connection before the end of the render, but if you log the errors you get the same on Application_Error - this is not a page error.
Exception of type 'System.Web.HttpUnhandledException' was thrown. --->
System.Web.HttpException: The remote host closed the connection.
The error code is 0x80072746.
In you Global.asax, handle Application_Error.
When a NullReferenceException is handled by the server a 500 response is created. Redirect all of your server 500 messages however you want. This guide will help.
Definitive Guide to Handling 500 Errors in IIS6, IIS7, ASP.NET MVC3 with Custom Page
You can hook up to every uncatched NullReference Exception, depending on what you want to do.
For instance you can use the global.asax, to be specific the Application_Error Event. You can get a reference to the exception, look for the type and perform a redirect there.
Another way to get ahold of exceptions would be to write your custom error provider, but that wouldn't give you the possibility to perform a redirect.
As is suggested elsewhere, I am using redirectMode = ResponseRewrite in my custom error configuration so my custom error page can access the exception info. This has worked like a charm for some time.
In adding some more "help the user recover from an error" type functionality, we need a piece of info that has been previously stored in Session. When implementing this, I found that the various avenues to Session end in null when redirectMode=ResponseRewrite, but they are all populated when redirectMode=ResponseRedirect (or isn't defined).
Anyone know why? It seems odd that we'd have to choose between having exception info (ResponseRewrite) or having Session (ResponseRedirect).
The MSDN article on Rich Custom Error handling tells me that Session is only available when the control passing method is Server.Transfer, which is what I assumed ResponseRewrite used under the hood. Evidently that isn't the case.
I don't know the answer to the question yet, but to get past it, I took the redirectMode attribute out of my web config and put custom logic in the Global.asax Application_Error handler to do what I wanted. I am replacing the exception with a "user friendly" message exception, but essentially the transfer logic is:
if(Context.IsCustomErrorEnabled)
{
Server.Transfer("~/Error.aspx");
}
Then the Error.aspx page has Page_Load code to pull the error out of context and display the message.
I have a web user control which my aspx page contains. During testing I discovered a exception being thrown. (The general rule that is in place, is that when an exception occurs the user is redirected to a excpetion page detailing the error)
Once the excpetion was handled in my User Control I wanted to throw it to the page where the parsing and redirect could occur safely. I do this in other circumstances by using the Global Asax, Application_Error to deal with the redirect etc. however all that happened when I threw the exception from the user contorl was I got a horrible javascript type dialog with the exception message.
To work around this I declared an Event which is then raised from the user control with the exception as the parameter. I can successfully parse the expception to the required format and redirect the user to the exception page.
My question(s) are these
Why does throwing the exception from the user control only result in the javascript dialog and not the Global.asax error
handling kicking in.
Is there a
way to force consumers of the
control to handle my custom error
event? Simialr to a "MustImplement" -----a "MustHandle" kind of affair?
Why does throwing the exception from the user control only result in
the javascript dialog and not the
Global.asax error handling kicking in.
Because there is a page error during an asynchronous postback, here's a good article on Error Handling in ASP.Net Ajax Applications.
2.Is there a way to force consumers of the control to handle my custom error
event? Simialr to a "MustImplement"
-----a "MustHandle" kind of affair?
This explains how to handle asynchronous postback errors in the Global.asax.
I'm not versed in ASP.NET but I'll give it a shot:
Why does throwing the exception from the user control only result in the javascript dialog and not the Global.asax error handling kicking in.
The error is raised on the client side, your error handling takes place on the server side. Unless you implement an AJAX-y callback that kicks in upon errors, the server isn't notified of any client-side errors. This doesn't seem to be the default behaviour in ASP.NET. You might check out Microsoft's AJAX library, surely they already have a mechanism for such things in place.
Is there a way to force consumers of the control to handle my custom error event? Simialr to a "MustImplement" -----a "MustHandle" kind of affair?
Simple answer: no.
What is the preferred method for handling exceptions in ASP.NET Webforms?
You have the Page_Error method that you add (I think) at web.config level, and the entire site gets redirected there when an error occurs.
Does that mean you shouldn't use try-catch anywhere in a webforms application? (Assuming you don't want to hide any errors)
Only catch the errors you can handle. If you can handle them in a manner that allows the page to continue loading then do so. Any other exception that would wreck the page should not be handled in any control or page as you would not be able to do anything anyways. Let it go to the global.asax handler and make sure you log the exception.
In addition to Andrew's suggestion, make sure to update the web.config file to set CustomErrors to "On" and specify a generic error page to redirect these top level errors. Global_asax will still log the error, and then the user can see a friendly page. It will also allow you to configure a few of the standard type errors, such as 404s and 200s, plus much more.
Web Application will normally consists of UI, Business and Data access layer.Each layer must do its part regarding exception handling. Each layer must (for code re usability) check for error condition and wrap exception(after logging it) and maybe propagated to the calling layer. The UI layer should hide exception and display a friendly message. Catching all exception in UI maybe not a good idea. Exceptions if possible should be logged in Database. This will allow ease of maintainence and correction of bugs
Avoid catching exceptions as far as possible. Try and validate all inputs before you use them. Rigorously validation( both client and server side) inputs with help of validation controls, custom controls and regular expression is a must.
string fname = "abc";
//Always check for condition, like file exists etc...
if (System.IO.File.Exists(fname))
{
}
else
{
}
Always make sure clean up code is called. Using statement or try finally.
You can catch all exceptions in Global.asax (asp.net application file)
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
Exception objErr = Server.GetLastError().GetBaseException();
string err = "Error Caught in Application_Error event\n" +
"Error in: " + Request.Url.ToString() +
"\nError Message:" + objErr.Message.ToString()+
"\nStack Trace:" + objErr.StackTrace.ToString();
EventLog.WriteEntry("Sample_WebApp",err,EventLogEntryType.Error);
Server.ClearError();
//additional actions...
}
and add <customerror> section in your web config to redirect user to a separate page
<customErrors defaultRedirect="error.htm" mode="On">
</customErrors>
Useful links
MSDN
MSDN
Exception Logging- Peter Bromberg
You should use try/catch in places where you can do something meaningful with error, like fixing it or taking a different approach.
For all other cases you should use global try/catch using web.config custom errors page or Application_Error event to log the error and possibly to show it to the user.
If you use validation controls or check and validate user input in your code behind that will go a long way to preventing errors. I do recommend having a generic error page that can log the error for you. In cases where you are unsure of what will happen i suggest catching the error and handling it if at all possible and work on finding a way to know that what you are going to run will work before doing it.
Do you have a specific example in mind of where you might expect to encounter an error of this sort. One that I know of is when a session expires and you can no longer process the page. I check for this on every page load before anything else is run and then redirect the user if this has occurred.