Sorry for the n00b question I'm about to ask. I tried doing some
Google searching and searching this group's threads but have yet to
find an answer to my issue.
I have a service function where I am intentionally causing an error
because I want to test that I can catch the error from my service
function in my endItem controller function.
I tried earlier to just abort inside the cfcatch in my service
function, but that's not working.
I'm calling index.cfm?action=contactus.submit in the browser.
On Fri, Jan 27, 2012 at 9:33 PM, wellercs <welle...@gmail.com> wrote: > I have a service function where I am intentionally causing an error > because I want to test that I can catch the error from my service > function in my endItem controller function.
Since FW/1 is calling your service, FW/1 will catch your error and invoke the error handling cycle (normally trying to run the main.error event). -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/
"Perfection is the enemy of the good." -- Gustave Flaubert, French realist novelist (1821-1880)
what i usually do is set returntype="struct" on all functions that return something. in the function i declare a var result = {}; and result.success = true; then in any cfcatch blocks (and other places, like data validation logic, etc) i set result.success = false; the function return the result structure (return result;) - the code that invoked the function would first check that result.success was returned true. if it was false that means that there was some error inside the function. i also usually set a result.err variable inside the function and populate it with any error messages i catch - the invoking code can then use this error message to email to me or display to user.
On Mon, Jan 30, 2012 at 4:43 PM, Azadi Saryev <azadi.sar...@gmail.com> wrote: > what i usually do is set returntype="struct" on all functions that return > something. > in the function i declare a var result = {}; and result.success = true; > then in any cfcatch blocks (and other places, like data validation logic, > etc) i set result.success = false;
There's nothing wrong with a service throwing an exception - if it's genuinely an exceptional condition and not just an expected "failure" result. The problem arises if you let FW/1 call services on your behavior because then you are limiting in how you handle exceptions. If you explicitly manage and call services yourself - my preference - then you can wrap calls in try/catch where appropriate. Remember that exceptions are essentially part of the public API of your service (because clients need to know about them). -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/
"Perfection is the enemy of the good." -- Gustave Flaubert, French realist novelist (1821-1880)
On Mon, Jan 30, 2012 at 8:05 PM, Sean Corfield <seancorfi...@gmail.com>wrote:
> If you explicitly manage and call services yourself - my preference - > then you can wrap calls in try/catch where appropriate.
... does this suggest that your preferred method is to place the try/catch within your controllers?
Although I've never really seen it discussed, I've always been curious about _where_ in their applications people choose to catch an error and deal with it.
As in, do you catch the exceptions in your service (or maybe even a gateway) and inform other components of the failure up the line, as Azadi does? Or do folks let the exceptions bubble up to, say, the controller, and handle all the aspects (logging, client messages, etc) there?
I know it's an "it depends" thing. Just wondering how you generally handle exceptions.
On Tue, Jan 31, 2012 at 5:32 AM, Tom McNeer <tmcn...@gmail.com> wrote: > On Mon, Jan 30, 2012 at 8:05 PM, Sean Corfield <seancorfi...@gmail.com> > wrote: >> If you explicitly manage and call services yourself - my preference - >> then you can wrap calls in try/catch where appropriate. > ... does this suggest that your preferred method is to place the try/catch > within your controllers?
It depends :)
If the service API includes thrown exceptions to indicate specific (unexpected) failures then, yes, I'd probably put try/catch in the controller around the service call. But...
A lot depends on how you want to handle unexpected errors. An exception is meant to be _exceptional_ by definition. If you make a service call and it fails (unexpectedly) due to a database problem, what are you likely to be able to do about it? Again, it depends. Inserting data and getting a data too big for column error indicates a failure to properly validate input in your application. You should probably let the default error handling in FW/1 kick in and open a ticket in your bug tracking system to add proper field validation. Calling out to a third party service and getting a connection error... should probably be encapsulated in your service as an "expected" failure (and either retried or a known, documented failure result returned to your controller). But there may be reasonable situations where your controller calls a service that is known to be able to throw a given exception and your controller could catch that and do something other than the default error handling behavior.
In other words, because exceptions should be exceptional and unexpected, the framework's default error handling is likely to be the most appropriate solution in most cases. But there could be exceptions (sic) to that "rule" :)
> Although I've never really seen it discussed, I've always been curious about > _where_ in their applications people choose to catch an error and deal with > it.
Error is a fluffy term. Exceptions are one thing. Expected failures are another. They should be handled differently. You should recover from a failure (because you expect it) but you probably can't recover from an exception (because it's unexpected).
On Tue, Jan 31, 2012 at 11:45 AM, Sean Corfield <seancorfi...@gmail.com>wrote:
> It depends :)
Maybe we need a new web acronym for that phrase, so we don't all have to keep writing it out.
Although - the natural acronym would be 'id,' which itself brings all sorts of Freudian issues to the already-fraught task of software development ;-)
> In other words, because exceptions should be exceptional and > unexpected, the framework's default error handling is likely to be the > most appropriate solution in most cases.
Okay. That's pretty much what I thought you'd say, with the obvious need for 'exceptions' to the rule.
> Error is a fluffy term. Exceptions are one thing. Expected failures > are another. They should be handled differently. You should recover > from a failure (because you expect it) but you probably can't recover > from an exception (because it's unexpected).
And I'll try to be less fluffy in the future.
I used the term 'error' simply because it can (hopefully up until testing is done) include not only 'failures' and 'exceptions,' but also 'stupid mistakes.'
Thanks for being willing to expound a bit on sort of a side issue.
> >Since FW/1 is calling your service, FW/1 will catch your error and > >invoke the error handling cycle (normally trying to run the main.error > >event).
@Sean - Thank you for your quick reply. I removed the try/catch code and the redirect (thinking that may have something to do with it), but it's not falling back to main.error. When I removed the redirects in the controller, I received an error stating the contactus.submit view was not found, which was expected, so I know the error view is working. I put the redirects back in, and it's still not providing feedback. Are you able to produce an error with the code I provided originally?
@everyone-else/@Sean - Thanks for the insightful comments on error handling in controller vs service layer.
> >Since FW/1 is calling your service, FW/1 will catch your error and >> >invoke the error handling cycle (normally trying to run the main.error >> >event).
> @Sean - Thank you for your quick reply. I removed the try/catch code and > the redirect (thinking that may have something to do with it), but it's not > falling back to main.error. When I removed the redirects in the > controller, I received an error stating the contactus.submit view was not > found, which was expected, so I know the error view is working. I put the > redirects back in, and it's still not providing feedback. Are you able to > produce an error with the code I provided originally?
> @everyone-else/@Sean - Thanks for the insightful comments on error > handling in controller vs service layer.
Follow up to my reply: I put a log statement <cflog text="hi"> in my contactus.cfc submit function in my services directory, and commented out everything else. I am not seeing the log statement printed in my console. My form is posting to 'index.cfm?action=contactus.submit'. It's my understanding that my service in this case would be called by FW/1 directly without me having to code anything in the controller since I have a cfc called contact us and a function called submit. Hopefully this sheds some light on the issue.
On Wed, Feb 1, 2012 at 7:18 PM, Chris Weller <welle...@gmail.com> wrote: > Follow up to my reply: I put a log statement <cflog text="hi"> in my > contactus.cfc submit function in my services directory, and commented out > everything else. I am not seeing the log statement printed in my console. > My form is posting to 'index.cfm?action=contactus.submit'. It's my > understanding that my service in this case would be called by FW/1 directly > without me having to code anything in the controller since I have a cfc > called contact us and a function called submit. Hopefully this sheds some > light on the issue.
>Which version of FW/1 and what is suppressImplicitService set to?
I am running 2.0.0 with the default settings, so suppressImplicitService was set to true! I now see this on the wiki. I apologize for not reading that well enough. I changed my code to EX-plicitly call the service, and it worked.
"Prior to FW/1 2.0, a service method was automatically called, with a name that matched the *action* and the result was placed in *rc.data*. FW/1 1.2 introduced a configuration variable to control this behavior and that variable is still present in 2.0, but the default behavior has changed so that service methods are not called automatically."
>In 1.x, FW/1 called a service automatically but 2.0 deliberately does >not. That setting lets you have 1.x behavior in 2.0.
Now that you have enlightened me, I like the fact that 2.0 suppresses the implicit service call. I like to have control over this and not worry about shooting myself in the foot by adding a service function at a later date that could affect other requests adversely.
Thanks again for your patience and prompt responses.
On Wed, Feb 1, 2012 at 8:52 PM, Chris Weller <welle...@gmail.com> wrote: > Now that you have enlightened me, I like the fact that 2.0 suppresses the > implicit service call. I like to have control over this and not worry about > shooting myself in the foot by adding a service function at a later date > that could affect other requests adversely.
Cool! With DI/1 it's very easy to manage your model / services and have FW/1 & DI/1 collaborate to autowire everything.
Now that FW/1 2.0 is gold, my goal is to have DI/1 hit 1.0 fairly soon. Then I can go back to cfmljure and get that into a more user-friendly format (not that everyone is going to be interested in using Clojure with CFML :) -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/
"Perfection is the enemy of the good." -- Gustave Flaubert, French realist novelist (1821-1880)
Oh noes! your user wasn't saved because: <p>#rs.error#</p>
</cfif>
But those are exceptions that are trapped, but if it is an exception that (for example) the database is down, that could be a general exception, so now, instead of of just throwing it we could re-throw it.
> On Mon, Jan 30, 2012 at 8:05 PM, Sean Corfield <seancorfi...@gmail.com> wrote: > If you explicitly manage and call services yourself - my preference - > then you can wrap calls in try/catch where appropriate.
> ... does this suggest that your preferred method is to place the try/catch within your controllers?
> Although I've never really seen it discussed, I've always been curious about _where_ in their applications people choose to catch an error and deal with it.
> As in, do you catch the exceptions in your service (or maybe even a gateway) and inform other components of the failure up the line, as Azadi does? Or do folks let the exceptions bubble up to, say, the controller, and handle all the aspects (logging, client messages, etc) there?
> I know it's an "it depends" thing. Just wondering how you generally handle exceptions.
> -- > Thanks,
> Tom
> Tom McNeer > MediumCool > http://www.mediumcool.com > 1735 Johnson Road NE > Atlanta, GA 30306 > 404.589.0560
On Tue, Jan 31, 2012 at 09:38, Mark Drew <mark.d...@gmail.com> wrote: > A controller does seem to be the best place for them since you want to > pass it along to the view.
> For example:
> UserService.save() throws UnknownUserException (or whatever you call it)
> The controller needs to know about that so it can do :
> <cfif Len(rs.error)> > Oh noes! your user wasn't saved because: > <p>#rs.error#</p>
> </cfif>
> But those are exceptions that are trapped, but if it is an exception that > (for example) the database is down, that could be a general exception, so > now, instead of of just throwing it we could re-throw it.
> (don't try this code at home, I just wrote it off the top of my head)
> MD
> On 31 Jan 2012, at 13:32, Tom McNeer wrote:
> Sean,
> Just curious --
> On Mon, Jan 30, 2012 at 8:05 PM, Sean Corfield <seancorfi...@gmail.com>wrote:
>> If you explicitly manage and call services yourself - my preference - >> then you can wrap calls in try/catch where appropriate.
> ... does this suggest that your preferred method is to place the try/catch > within your controllers?
> Although I've never really seen it discussed, I've always been curious > about _where_ in their applications people choose to catch an error and > deal with it.
> As in, do you catch the exceptions in your service (or maybe even a > gateway) and inform other components of the failure up the line, as Azadi > does? Or do folks let the exceptions bubble up to, say, the controller, and > handle all the aspects (logging, client messages, etc) there?
> I know it's an "it depends" thing. Just wondering how you generally handle > exceptions.
> -- > Thanks,
> Tom
> Tom McNeer > MediumCool > http://www.mediumcool.com > 1735 Johnson Road NE > Atlanta, GA 30306 > 404.589.0560