views:

281

answers:

4

Hi, I am just starting with ASP.Net. I copied a ex-co-worker's code (from .Net 1.1 era) and it has a Response.End(); in case of an error. There is also a:

        catch (Exception ex)
        {
            Response.Write(ex.Message);
            Response.End();
        }

at the end of Page_Load(object sender, System.EventArgs e) which always appends "Thread was aborted." or something like that at the end. I suspect that this worked differently before, or the error conditions were not tested very well.

Anyhow, I was able to stop using Response.End(); in case when I do not like the GET parameters, and use return; instead. It seemed to do the right think in a simple case.

Is this Ok in general?

There are some problems with the code I copied, but I do not want to do a rewrite; I just want to get it running first and find wrinkles later. The Response.End(); caused a mental block for me, however, so I want to figure it out.

I want to keep the catch all clause just in case, at least for now. I could also end the method with:

        catch (System.Threading.ThreadAbortException)
        {
            Response.End();
        }
        catch (Exception ex)
        {
            Response.Write(ex.Message);
            Response.End();
        }

but that just seems extremely stupid, once you think about all of the exceptions being generated.

Please give me a few words of wisdom. Feel free to ask if something is not clear. Thanks!

P.S. Ex-coworker was not fired and is a good coder - one more reason to reuse his example.

+1  A: 

You shouldn't be catching all your exceptions at this level. Use the Application_Error event in the global.asax to handle unexpected errors and provide a custom error page to show to your clients (see the customError section in the web.config).

In general, you should only catch exceptions you should handle, and you should not output error trace to your users. The response.end he is using is only required due to this odd error handling technique.

Paddy
True ... but it is for internal use, so i can be semi-professional here. Good to know though.
Hamish Grubijan
+2  A: 

According to the MSDN, all this call does is stop processing and return the current results. Therefore, calling Response.End() at the END of your processing should have no effect.

In practice, I've only used this to abort current processing mid way through.

Tom Tresansky
What if I do `Response.Write("error"); Response.Flush(); return;` mid-way? Is that good enough. I still want to keep the catch all, as stupid as it seems.
Hamish Grubijan
Like @Artiom mentioned, if there is additional processing that would normally run after the catch block, calling Response.End() prevents it from running. If there is none, you should see no difference in anything be removing that line from the catch block. Adding a `Response.Flush(); return;` will leave the current Page_Load() method and allow any other subsequent page lifecycle methods to fire normally. The `Response.End()` call will prevent these other methods from affecting the response, assuming they do exist.
Tom Tresansky
+1  A: 

Look at it this way.. If your page has any other page methods that run after Page_Load in the page lifecycle (Page_Render, Page_PreRender), or if there is any other code directly after the try-catch - then you should leave the Response.End() in place.

If there's nothing like it - then you can remove them if you want, nothing should happen differently. But taking into consideration that this is an old internal (even legacy maybe? copied from .NET 1.1) app, not written by yourself, you can probably leave them in place.. They will definitely not hurt, and might save you from hard-to-catch strange problems, which are usually found in legacy apps :D

Artiom Chilaru
+2  A: 
 catch (System.Threading.ThreadAbortException)
    {
        Response.End();
    }
    catch (Exception ex)
    {
        Response.Write(ex.Message);
        Response.End();
    }

This actually won't even work. ThreadAbortException is a special case exception, and when your catch block is done, it is automatically re-thrown.

Just using return is definitely the best case, if the method you are in is the last thing that will be run in terms of your code. If it's not, and you want to end the request gracefully, you can call HttpApplication.CompleteRequest(), which will skip processing the rest of the lifecycle and jump directly to the EndRequest event processing.

womp
It might not supposed to work, but ... it does! Also, what about using `Request.Flush();` in conjunction with `return;`?
Hamish Grubijan
Sorry - I should clarify. That will catch the exception, so the code will do what you want. But it won't suppress the exception - it will still propagate out to any higher-level exception handling, and beyond. Using Response.Flush() will simply send any output that has been written to the response stream to the browser. It is done as soon as the request is finished processing anyway, so unless you've got a long running process, there's not much point. It can also complicate certain ajax operations and session creation in some cases if you call flush too early.
womp
Now it makes better sense. Thanks!
Hamish Grubijan