An anonymous user (hey why not share your name?) asked this today:
I'm working more and more with cftry/cfcatch, but I'm still finding it confusing as to when to use a <cfrethrow> tag and the <cfthrow> tag. When would I use each?
This is a good question. I mean, we (developers) spend most of our time browsing blogs... err I mean trying to prevent errors. Why in the heck would you generate an error on purpose? Let me tackle each one and discuss why they would be used.
First off - why would you use cfthrow? In case you don't know, cfthrow lets you raise an exception. You can specify the exception type, message, detail, and other settings. Why would you do this? There may be cases in your business logic where it makes sense. A classic case is usernames. You normally do not want to allow multiple users with the same username in the same database table. Therefore, your "AddUser" logic may have logic that checks for an existing user with same name. If you find one, what do you do? Well, you could simply raise a flag. I've seen some developers who like to return structs from methods and store all kinds of information in them. They will store a return code, a return message, etc. Personally, I don't care for this. I think if your intent is to show that something has gone wrong, than an exception makes perfect sense. I know my readers will argue back and forth on this, but that's my opinion.
The typical place I will use cfthrow is inside CFC methods. My calling code will then use try/catch where appropriate. If you want an example, you can download Soundings and check out survey.cfc. (And other CFCs in the package.)
So why use rethrow? I think the example livedocs provides is a pretty good one. I'm going to crib their example code. (Adobe, if you mid, just let me know.)
<h3>cfrethrow Example</h3> <!--- Rethrow a DATABASE exception. ---> <cftry> <cftry> <cfquery name = "GetMessages" dataSource = "cfdocexamples"> SELECT * FROM Messages </cfquery> <cfcatch type = "DATABASE"> <!--- If database signalled a 50555 error, ignore; otherwise, rethrow exception. ---> <cfif cfcatch.sqlstate neq 50555> <cfrethrow> </cfif> </cfcatch> </cftry> <cfcatch> <h3>Sorry, this request can't be completed</h3> <h4>Catch variables</h4> <cfoutput> <cfloop collection = #cfcatch# item = "c"> <br> <cfif IsSimpleValue(cfcatch[c])>#c# = #cfcatch[c]# </cfif> </cfloop> </cfoutput> </cfcatch> </cftry>
Notice that the code uses try and catch to run a database query. There is a cfcatch block which specifically catches exceptions with type="Database". However, they do not want to handle cases where the SQL State is not 50555. (Whatever that is.) By using cfrethrow, they can say, "Oops, you know, we caught this exception, but upon further review we have decided it is really someone else's problem. Thanks. Call again." Basically, the rethrow is a way of "changing your mind" about catching the exception. To be honest, I don't think I've ever used this tag.