Cannot Transfer request to Desired ASP.NET Error Page - asp.net

In the Page_Load() section, I check for valid inputs & incase they are invalid, I transfer the request to a custom error page.
While doing so, a ThreadAbortException is thrown which is caught by my catch block but asp.net transfers the request to unknown exception page.
What am I doing wrong? I dont want the ThreadAbortException to come when I transfer to the error page.
eg:
protected void Page_Load(object sender, EventArgs e)
{
try
{
if (String.IsNullOrEmpty(szProductName))
{
//Product name not given. Hence cant process further.
Server.Transfer(Constants.ERROR_WRONG_INPUTS_ASPX);
}
else
{
//Do something.....
}
}
catch(Exception Ex)
{
}
}
As a workaround, I now use:
Response.Redirect(Constants.ERROR_WRONG_INPUTS_ASPX, false);
instead of Server.Transfer i.e. I allow the process to continue in the background which made required I check for validity & then only executed the remaining code.
My problem is similar to : Exception Handling Application Block Exception Handler running in ASP.NET cannot call Response.End() but it seems it was not answered.

Response.Redirect throws the ThreadAbortException to abort the current page and transfer control to the new page. Adding the false parameter "fixed" this problem because it tells Response.Redirect to complete processing on the current page before transfering control.
I believe though you need to look at your application flow. Having a page transfer to an error page because of input errors seems like an overly complicated way to handle input validation to me. I think you are better off with a postback that displays messages, or doing some validation in javascript before the page is posted.

Any time that Response.End() is called, a ThreadAbortException will occur. Server.Transfer calls Response.End() internally because it immediately ends the current processing and hands off the request to the new page, which becomes responsible for returning information to the browser.
Response.Redirect is more graceful, as it finishes processing the current request and returns a 301 Redirect response to the client. Generally this causes the browser to do a second request to the server to request the redirect URL.
You say it's transferring to an unknown error page, but I'm not sure why. Are you doing so in your Application_Error method in Global.asax? If the error is handled you should be able to control where it's heading off to.

I sugest you get rid of that try...catch block. What are you expecting to catch out there? If you really expect some exceptional situation that depends on your implementation, that would happen further down inside your else block. So you should wrap it with try...finally there.
ASP.NET throws the ThreadAbortException when ending your request but it catches it eventually upper in the call stack so you should not catch that yourself. If you're expecting some other possible state corruption just let it propagate up to the global exception handler; it's not your code that throws.

If a product is missing or if the product isn't in your data store then you might want to consider returning a 404 (Page Not Found). This indicates to the browser - (and to google search spiders!) - that there isn't such a page. Are you planning on using SEO friendly URLS such as:
http://MyServer/MySite/Products/FireFox?

Related

ASP.Net Global Error Handling and Error Site?

I am having a huge website with over 100 single sites in ASP.Net.
Of course I try to catch every action with a try-catch block or with other things like validation-controls.
But I want, IF a error happens which I get not catched to happens following:
1) Write the Error in Database
2) Show user a specific site instead the errorsite from asp.net
How to do that?
You can use the Application_Error event handler in in Global.asx to handle any exceptions that are not caught at the page level. See, for example,
http://msdn.microsoft.com/en-us/library/24395wz3(v=vs.100).aspx
It's kind of up to you what you do in the event handler, so you can log the error to a database if you want to. You can also redirect to another page of your choosing to display the error however you want.
Note that the Application_Error event will be raised for all uncaught exceptions, including Http exceptions (e.g. 404 Not found). You probably don't want to log those.
You should try ELMAH
Check out the blog post of Scott Hanselman on how to integrate it in asp.net website and make it work.
Below is the article from Scott Mitchel on how to log errors with Elmah and how to show custom error page to user:
http://www.asp.net/web-forms/tutorials/deployment/deploying-web-site-projects/logging-error-details-with-elmah-cs
http://www.asp.net/web-forms/tutorials/deployment/deploying-web-site-projects/displaying-a-custom-error-page-cs
If you not into trying elmah, which is a breeze to setup. It depends on how your 100 sites are setup. But you possibly could look into using the global
Application_Error event in global.asax.cs and add you own handling code in there.
protected void Application_Error(object sender, EventArgs e)
{
var lastException = Server.GetLastError();
//log it to db, re-route the request to an alternate location ... etc
}
Another option, again it depends on how your sites are setup/hosted would be to read the event_log on the server, and check for ASP.NET errors saving the relevant details to the db.

Have Page Method Unhandled Exceptions Behave as Other ASP.Net Unhandled Exceptions

I have a webform that has a single page method. My other web apps log unhandled exceptions to the system event log on the web server. Since the other developers that I work with expect to see entries for app errors in the event log, I would like this app to do the same.
However, I have the app send error emails when an exception is caught from calling code inside the page method. It is not writing to the event log when this occurs. Note: the page method re-throws the exception after calling my email notification method.
From what I've read so far it seems that ASP.Net logs errors to the event log by default. I imagine that the same is not true for Page Methods/WebMethods because they basically throw the exception to the client code calling it.
Is there a trivial way to have that exception bubble up properly so that it writes to the event log? No other apps write to the event log directly from what I've seen so I don't think the application could create a new source since our security people keep a lot of things locked down (with good intentions, yay security).
[WebMethod]
public static object MyPseudoWebMethod()
{
try
{
// My exception spawning unreliable code here
}
catch(Exception ex)
{
// Cleanup ...
this.SendErrorNotification(ex);
throw; // <-- This doesn't bubble up but I'd love for it to!
}
}
Hmm interesting problem. You are right in that WebMethod exceptions do NOT follow normal exception flow.
The Application_Error event is not fired if your web method throws an
exception. The reason for this is that the HTTP handler for XML Web
services consumes any exception that occurs while an XML Web service
is executing and turns it into a SOAP fault prior to the
Application_Error event is called.
(from here)
The above page suggests using a SOAP extension to catch that exception before its swallowed, but here's how I'd do it if you don't want to do that:
1) Make a new 'error recieving' ASPX page that you will build that will take whatever params you want to record in your error log. So for example, have this page take in a POST named "ExceptionDetails" or whatever else you wish to capture. This page will NOT be viewed directly in a browser, so it doesnt need any ASPX controls or anything, but using a MasterPage on it won't hurt anything.
2) In the code behind of this new page, grab whatever POSTS you are sending in and new-up an Exception with whatever details you need. Immediate throw this exception. Doing this means that this exception will follow whatever flow other unhandled exceptions follow in the app (logging, emailing, etc).
3) On the page that calls the WebMethod JS, Wrap the calls to the WebMethod in a try-catch
4) In the catch block, print out whatever message you want in the browser, and initiate a new AJAX post to that new error receiving ASPX page, passing along whatever POST stuff you made that page look for.
The new AJAX call will NOT change ANYTHING in the user's perception by default. The AJAX call fires off a new request to that page, and the ASPX page itself is actually totally unaware that its AJAX and not a normal browser request. Any cookies/session/authentication data that's currently set are available to the AJAXed page as well, if you are recording a user's ID or anything. If you look at the returned response from a tool like Firebug, you will see that its actually the YellowScreenOfDeath's HTML (unless you have a custom 500 page, in which case its that HTML that comes back).
This is simply how the legacy ASMX web services work.
The only workaround is to stop using them (which you should do anyway, unless you're stuck with .NET 2.0). WCF doesn't have this problem.

Is it possible to write a base class to handle nullReferenceException from all pages?

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.

AJAX Partial Rendering issues for the default page in IIS 7 when using custom http module

The problem
When I try to make a AJAX partial update request (using the UpdatePanel control) from the default page of an IIS7 web site, it fails- instead of returning the html to be updated, it returns the entire page, which then causes the MS AJAX Javascript to throw a parsing shit-fit.
The suspected cause
I have narrowed the cause down to two issues- making an AJAX request to the default page when I have a certain custom http module registered. A partial rendering request to http://localhost will fail, but a partial rendering request to http://localhost/default.aspx will work fine.
Also, If i remove the following line in my custom HttpModule:
_application.PreRequestHandlerExecute += OnPreRequestHandlerExecute;
The AJAX partial render will work correctly. Wierd huh?
Another wierd thing...
If I look at trace.axd, I can see that when a partial rendering request fails, two POST requests are logged for the one partial rendering request- one where the default.aspx page executes successfully (trace information such as page_load is logged) but no content is produced and a second that doesn't seem to actually execute (no trace information is logged) but produces content (HTTP_CONTENT_LENGTH is greater than 0).
Please help!
If anyone with a good knowledge of HTTP modules or the MS AJAX Http module could explain why this is occuring I would be very grateful. As it is, the obvious work arround is to just redirect to default.aspx if the request url is "/" but I would really like to understand why this is occurring.
First of all PreRequestHandlerExecute is exactly before HTTP handler executes.
Second for hosting websites with HttpModules under IIS7 it is better that we run website in integrated pipeline mode, and also we have to move HttpModules tag in web.config to system.webServer module section.
If for example you change the handler in PreRequestHandlerExecute like this:
void context_PreRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
HttpContext context = application.Context;
if( something-happened )
context.Handler = null;
}
The result would be exactly as you said.
Setting handler to any thing else but its default, means that ASP.Net is not responsible for current request.
Note that each request only can have one HttpHandler.

Exception handling in ASP.NET Webforms

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.

Resources