CFFinally Tag Will Execute Even After An Abort In ColdFusion
This is just a quick sanity check. Earlier this year, I tested to see if the CFFinally tag would execute if the CFCatch block threw an error; which it did. Along the same lines, I wanted to see if the CFFinally tag would execute if the CFCatch block tried to abort the request processing.
To test this, I created a CFCatch block that executed a CFLocation tag. Usually, the CFLocation tag would prevent the rest of the request from processing. So, to test execution paths, I'm overwriting the "Location" header in the CFFinally block:
<cfscript>
try {
throw( type = "Vadar", message = "I find your lack of faith disturbing." );
} catch ( any error ) {
// NOTE: I also get the same exact behavior if I use an Abort tag instead
// of a location tag - but, the location makes the experiment a little more
// fun to do, am I right?
// --
// abort;
// The location tag usually aborts processing.
location( url = "./location.cfm", addToken = false );
} finally {
// Try to overwrite the Location header that has been set by the CFLocation
// tag in the CFCatch block.
location( url = "./finally.cfm", addToken = false );
}
</cfscript>
As you can see, the CFLocation tag is trying to redirect to "location.cfm" and the CFFinally block is trying to redirect to "finally.cfm". When we run the above code, we get the following network activity:
GET finally.cfm 404 Not Found
Based on the network activity, we can see that the CFLocation tag in the CFFinally block executed even after the CFCatch aborted the page request.
Now, I know what you're thinking - you're not actually "aborting," you're just invoking a CFLocation tag. True. But, I get the same exact result if I replace the first CFLocation tag (in the CFCatch block) with a CFAbort tag, proving that the CFFinally tag will execute after an abort. But, the CFLocation makes the experiment more interesting because how often have you ever seen two CFLocation tags executing on the same request?
Want to use code from this post? Check out the license.
Reader Comments
That's the point of finally tags-- they always, always, ALWAYS execute. In lower level languages like Java, that behavior is imperative. Otherwise you'd end up with file and socket streams left open, etc. It is interesting that the finally location executes. It must mean that CF somehow queues up the first location, runs the finally, and then goes back to the first location (which doesn't happen here). What if you put two locations in your finally? :P
I'm also curious if Railo is this hardcore and making sure the finally's execute.
@Brad,
It's funny, you just get so used to "abort" being the "final say", that it's hard to imagine that anything else can run after it. When in doubt, I test it out :D
I'm just guessing here, but I assume the CFLocation tag is just setting the status-code and the "Location" header. So, I assume the second CFLocation tag is just overwriting the Location header before the response is committed back to the client. But, just a guess.
@Brad,
Railo's not very hard-code when it comes to finally. See the bug I just raised here: https://issues.jboss.org/browse/RAILO-3132
:-(
(CF, on the other hand, runs as expected).
--
Adam
Ha. Railo have already fixed this. Astoundingly good work from them.
@Adam,
Those Railo guys are so freaking agile. No matter what, you have to given them that! Awesome stuff :)