- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
The real WTF is why is the coder wasting CPU cycles trying to catch exceptions here. There is no need for the try block. As for the ThreadAbortException, you have to do that to eat the exception automatically generated by Response.Redirect.
Admin
ROFL
I get it! a VB 'programmer' trying to understand the try/catch construct!
That's NEVER gonna happen! WTF!
Admin
[8-)]
I really like the empty Finally block too.
Admin
http://support.microsoft.com/default.aspx?scid=kb;EN-US;312063
the boolean tells the code whether to stop the response at the point of
redirect, or not. By default, it is true, so a ThreadAbortException (I
believe) is thrown behind the scenes to signal to the framework to stop
processing the last request immediately (note this is important as any
code past that point could be run if it were set to false). For the
default value of true, you don't notice the exception of course, unless
you do a redirect inside of a try...catch block. Then you'd want to use
the overloaded method passing in false for 'end response' arg.
Admin
Well, technically it's correct. Response.Redirect calls Response.End which always throws the exception. (Maybe that's the real WTF: a method that always throws an exception!) See:
http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemWebHttpResponseClassRedirectTopic1.asp?frame=true
http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemwebhttpresponseclassendtopic.asp?frame=true
However, it is a WTF because a better solution exists: Response.Redirect(targetUrl, false): http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemwebhttpresponseclassredirecttopic2.asp?frame=true .
Have a nice day!
Admin
I've been curious about this before too. In fact I've written similar code:
[code language="c#"]try
{
Response.Redirect("thankyou.aspx");
}
catch (ThreadAbortException) { }[/code]
I guess I was used to the way regula' old ASP did a redirect - by ending the processing of the current request. And this is not the way the creators of ASP.NET were thinking.
Lesson learned.
[code language="c#"]Response.Redirect("thankyou.aspx", false);[/code]
Admin
Ack, the WTF in this post is the COLOR SCHEME!!!
Another guy getting nostalgic for DOS 3.3? Or what?
Admin
Or maybe we can just randomly add
System.Threading.Thread.CurrentThread.Suspend();
System.Threading.Thread.CurrentThread.Resume();
Admin
If you use the optional second parameter of the ASP.NET Response.Redirect method, the one named endResponse, the Exception will never be thrown, as the thread will not be aborted prematurely.
http://support.microsoft.com/default.aspx?scid=kb;en-us;312629
Admin
I get it! The WTF is not in the code but in the comments...
The first WTF comment says:
<font color="#008000">'Do nothing as response.redirect always generate this exception</font>
But it should say
<font color="#008000">'Do nothing as response.redirect always generate this exception unless
'I call the overloaded redirect with that endResponse extra parameter
'that avoids the exception being thrown and performs better, this because
'I'm to lazzy to read the API docs or even looking at the options that
'intellisense brings me.</font>
The second says
<font color="#008000">'Propagate exception</font>
And it should say
<font color="#008000">'Who said I was lazy?
'Look how I'm catching an exception here just to throw it again
'just for the sake of doing it.</font>
And there’s a block of code lacking of a comment that should say.
<font color="#008000">'Maybe is just me but a try block looks faulty without the finally part.</font>
Admin
You DO NOT need to swallow ThreadAbortException. In fact, if you find yourself doing so there's probably something wrong with your code. The framework throws that to unwind your thread when it ends the request. An exception is the only way to do this cleanly. If you've got more processing going on there that has to happen after you've Response.Redirect'ed or Server.Transfer'ed you either need to move that processing somewhere else or use the optional parameter to inform the framework not to terminate processing on this thread.
Moreover, catching ThreadAbortException WILL NOT stop it from propagating up the call stack. It's special in this regard because in general it's not supposed to be caught. The only way to "swallow" TAE is to call Thread.ResetAbort(). But again, you really ought not to be doing that anyway.
So really, whenever I see someone trying to swallow TAE, that's a WTF to me.
Admin
>It's special in this regard because in general it's not supposed to be caught.
That really ought to read "swallowed" instead of "caught."
Admin
Seeing a variable declared within the TRY block (which is never used) actually reminded me of what I theorize must be the only reason for a FINALLY section to ever exist: variables declared within the TRY are still in scope. Otherwise, what is the point of the FINALLY section?
Admin
anonymous: The point of the finally is to close any connections or files that may still be open.
try
{
connection.open();
int.parse("A");
}
catch{}
finally
{
connection.close();
}
Admin
(sorry, Anonymous was me, I wasn't logged in)
Yes, I understand in theory its there so you can "clean up", that's fine, but there is no difference between doing it in the finally block or doing it right after -- unless you wish to reference objects declared within the TRY that would otherwise be out of scope.
Your example is easily written as:
try
{
connection.open();
int.parse("A");
}
catch{}
connection.close();
and does the exact same thing, since the object "connection" is still in scope after the TRY/CATCH code is completed, whether there's an exception or not. Make sense?
Admin
(me again)
and actually, your example (which I ended up using) is a bad one because the finally() block might cause an error if the connection never did open successfully. remember, finally() is executed whether or not an exception occured, not just if the TRY was successful.
Admin
Except that the finally will ALWAYS execute; programmatic control may be thrown to another module/class/procedure by the exception. Not every try needs to have a local catch associated with it; the exception may be caught several layers upstream.
(Stan Rogers, who has not yet created a local ID here.)
Admin
@Jeff,
In this code the connection will never be closed because when there is an exceiption within the try/catch the code stops executing at the end of the catch block, it doesn't continue on to where you are closing the connection, which is outside of the try/catch block. That's why a finally block is needed.
Admin
Sh1t, disregard this, I was drunk a few minutes ago when I wrote this[:S]
Admin
Stan -- can you give an example?
Admin
Well, it IS possible to create a catch that is the equivalent of On Error Resume Next, so you can't say that the close() will never be caught just because it lives lower down the page.
Admin
hmmm... I think you missed the point -- it wasn't to criticize your code! it was to indicate that what you posted in no way requires a FINALLY clause. no worries, though.
Admin
An exception will be thrown to the lowest-flying catch that accepts its signature. If you call a method from within a try block, which in turn calls a method that has a try block, and only initial calling method has a catch that accepts an exception that's thrown in the lowest-level try block, then the exception will be caught by the calling method's catch block. That may transfer control elsewhere or halt the whole application, there's no guarantee that (in the example) close() would ever be called. If it's in a finally block, it will be called regardless of where the high-level catch sends the rest of the execution stream.
Admin
A ha! i think i got it:
Try
i = i / 0
Catch ex As Exception
MsgBox("exception is caught")
Exit Sub
Finally
MsgBox("Finally")
End Try
The "exit sub" still executes the FINALLY block of code ! now, I get it! I just couldn't wrap my mind around this until I considered an exception that exits the procedure or function.
Thanks!!
Admin
A more common situation needing finally would be:
try
{
connection.open();
// do some work using connection which could throw
if(something == 5) return;
// do more work
if(somethingelse == 3) return;
// etc.
}
catch(Exception ex)
{
// report error
}
finally
{
connection.close();
}
Without the finally, those test become similar to:
if(something == 5)
{
connection.close();
return;
}
So if you can imagine having several exit points and several connections, files, etc. that need to be cleaned up you get a lot of redundant code, and if certain items only need to be cleaned up after you've reached a certain point in the process then you either needlessly test them everywhere or risk missing necessary cleanup.
Admin
Actually, the above should look like this so to make it programmatically correct...
This should provide the correct functionality. And after Response.Redirect("page.aspx", true) happens, no more action is requried on your part.
Admin
You are all missing my favorite part of the code, which is the misspelt comment that says <font color="#008000">'Initialise the page </font><font color="#000000">followed by a commented out call to InitPage(). You know this whole mess of a coding exercise started with two lines of code, the call to Response.Redirect and the call to the InitPage() function and degraded once they realized that InitPage wasn't being called. Now the function call is gone and the mess remains, oh the irony [8-)].
bj</font>
Admin
Whoa holy crap I can't believe someone did that, what a waste of resources and it totally shows that... LOL bah screw it, I can't even pretend. I have no clue what's going on because I'm a lowly VB "programmer" (as someone so demeaningly referred to us yesterday). I can guess at what's going on though.
It's like having an If structure where you put in an Else statement but don't actually have anything happen there. To compound the matter, it would be like saying "If 1 = 1", which is ALWAYS true (except for when the skies open and fire rains from the heavens and the Rapture is upon us). Am I close? Do I win a prize if I am?
Admin
Even better solution is to use "using" clause (we are talking C#, aren't we?): http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csref/html/vclrfusingstatement.asp
Connection should implement IDisposable though (which should check if it is opened and call close).
Admin
Hate to be the spelling police, no I don't I love it.
Initialise is spelt correctly if your from the UK, we just have to suffer the bastardisations of the english language and colourful interpretations of the original form by Americans who changed it because it was too hard.
[;)]
Admin
In Tagalog, "tae" means feces. Umm. Just wanted to share...
Admin
uh oh. Jeff is a vb coder. That explains why he doesn't understand try/catch/finally.
Personally, I think typing
ON ERROR RESUME NEXT
at the top of the page solves all your problems.
vb programmers should be kept inside their own little world so that their code doesn't leak out into the real world. So that those who know what they're doing can sit back and write proper code, and those who dont can sit in their own little world writting rubbish code in vb.
Admin
[6]
Condeming VB programmers is not fair! I am a VB programmer, and I also know Assembly, Pascal, C, C++, Java, C#, and J#. So you are saying that because I use VB to develop a program I am not skilled enough? Well go ahead and condem all the programmers at Microsoft that developed the Office Suite. It is written in VB[8o|]
Admin
That's a pretty bold thing to say, especially considering you didn't even have the guts to post a name!
Yes, very clearly all I know is VB ! That is quite apparent, since I never saw the need to use a FINALL clause in my app; how can someone be a true programmer w/o ever using that feature? it's impossible! Any programmer who knows C or C++ (or assembly language for that matter) clearly should know about TRY/CATCH/FINALLY from using those languages, right?
Very, very sad! I look forward to seeing some of your code highlighted here in the future! Your comment about "just adding ON ERROR RESUME NEXT" to solve all the problems here is very telling, indeed!
Admin
For someone who refuted the usefulness of the Finally statement a few posts back, you got awfully stirred up by that lame VB insult!
(not the same Anon as any of these other posts)
Admin
Disregarding the myriad ways that one can avoid the System.threading.ThreadAbortException being thrown in the first place, the code looks to deal with it fine. Not the most graceful way of dealing with it, I grant you, but still. The other way of doing it, I guess would be:
This adds one more operation to the process - Catch the error, get its type, and act accordingly, move on to the finally block.
Doing it the way he has, has cut half of that process out - Catch the specified error and act accordingly (in this case, doing nothing) and then move on.
I'm not saying it looks pretty, but in the circumstances, it's OK. I think.
Admin
Sorry, I did not mean to "refute the usefulness" -- I simply asked WHY is it useful, because I didn't know! and now I do! Is that a bad thing? I guess my mistake was to ask for some guidance on a topic I needed some clarification on.
Admin
@Jeff: To add to your last comment, the finally block also executes if the exception is rethrown.
try
{
//something
}
catch (Exception ex)
{
throw ex;
}
finally{}
Admin
Thanks, Scott !
Admin
I would have done something more like this...
Dim responseUrl As String
Try
'Build responseUrl in try because it looks
'like we are calling methods that may fail
responseUrl = "GLSCWizard_SA.aspx?stat=" & Enumerations.PageState.Add_Mode & "&seid=" & lSurveyEventID & "&said=0")
Catch
ex As SomeOtherExceptionBesidesSystem.Exception
'Do something meaningfull if Try code fails
throw
'Redirect if no errors occured above
Response.Redirect(responseUrl)
Admin
I would have done something more like this...
Dim responseUrl As String
Try
'Build responseUrl in try because it looks
'like we are calling methods that may fail
responseUrl = "GLSCWizard_SA.aspx?stat=" & Enumerations.PageState.Add_Mode & "&seid=" & lSurveyEventID & "&said=0")
'Line break above was in wrong place
Catch ex As SomeOtherExceptionBesidesSystem.Exception
'Do something meaningfull if Try code fails
throw
'Redirect if no errors occured above
Response.Redirect(responseUrl)
Admin
Jeff : What about a Catch that just ReThrow the Exception... you'll also need the finally.
Admin
To be quite honest, I think the WTF is from Microsoft here. Why on Earth should moving control to a different page cause an exception???
I suppose that if you're one of the object-obsessed, Ada-worshipping types that seem to have resulted from the object explosion of recent years, you can justify this sort of thing. But personally, if I'm moving control from one part of my application to another, I don't expect my language framework to complain!
Admin
ThreadAbortException ... [:-*]the thread is being aborted
Better to use using for connections...
using(SqlConnection connection = new SqlConnection())
{
}
Admin
Thought i would add to the flame :) This is the proper use of a try block, some may argue... some may agree.. but hey, whatever floats your boat... if there are any exceptions thrown, they're caught at the application level and logged using my SystemFramework.ApplicationLog and SystemFramework.ApplicationTrace objects.
don't catch everything under the sun [:@] i.e. catch ( Exception ex )
Not only is it bad practice, but the overhead.......
Thanks! [:D]
P.s. -- wrote this right here in the post, so if there's issues..... oh well
Admin
OH of course--- the class that implements this code -- implements IDisposible, and the code that calls this class includes
using ( DataAccess.myClass myClassDataAccess = new DataAccess.myClass() )
{
// call the object i just showed you here
}
Admin
DJDanNY:
You're an ass. There are more than enough examples of poor coding practices in all languages. Some of the worst are in languages like C where you can do some real damage with pointers and no bounds checking.
The language wars are over. Get over it.
Scott:
You just need to check the state of the connection before you try to close it:
try
{
connection.Open();
int.Parse("A");
}
catch{}
finally
{
if( connection.State = ConnectionState.Open)
{
connection.Close()
}
}
Dave - http://www.geekswithblogs.net/dtotzke
Admin
Or... you could just dispose it ;)
Admin
Why have an empty catch block? It isn't required, and won't accomplish anything.
try
{
connection.Open();
int.Parse("A");
}
finally
{
if( connection.State = ConnectionState.Open)
{
connection.Close()
}
}
Admin
<font style="BACKGROUND-COLOR: #efefef">*** see code and comments above in my previous post... [:D]
BAD empty CATCH !! BAD!!!!!!! Makes for poor debugging..... and poor error handling... wait... "error handling"... if something does throw an error... the world may never know!!! [:O]
</font>