RE: [coldbox:17083] [ColdBox 3.5.2] Exception "handling" weirdness

> it absolutely should not do anything like this by default

I appreciate your opinion on the matter, but I’ll have to disagree. People use frameworks because they do things for them. If a framework doesn’t make your life easier, why would you bother using it? Every CF framework I’m familiar with catches errors in your code in a similar fashion. Frankly, in the years I’ve been on the ColdBox list I’ve never heard anyone else complain about the ColdBox error handling, which if I might add, by default displays more ColdBox-related information and is therefore more helpful than the standard CFML engine’s error message. It seems the vast majority of people want to use the framework’s error handling capabilities, and we’re not going to change that default behavior.

To turn the tables on you a bit, I would ask you this question: If you didn’t want ColdBox catching your errors, why did you allow them to bubble up to the framework in the first place? Wrap a try catch around all your code and ColdBox will never touch your errors again. That sounds rather painful to me though. I’d really rather just embrace the incredibly helpful and flexible tools that ColdBox gives you to deal with your errors.

If you really want the exception to reach the CFML engine, this can be accomplished very easily with the following simple interceptor I just threw together. All it does is listen for exceptions and rethrow them.

/interceptors/rethrow.cfc

component {
function onException(event, interceptData) {
throw(object=interceptData.exception);
}
}

/config/ColdBox.cfc
interceptors = [
{class=“newApp.interceptors.rethrow”}
];

> CB returns doesn’t even set the HTTP response code to be 500. It’s a “200 OK”.

Yes, that’s correct. That would be because the application has recovered from the error and returned useful HTML that it wants the browser to render. Returning a 500 would make many browsers (at least IE, I know) show a “friendly” error message of its own which would defeat the purpose of your error template. If you would like a different status code, you can easily configure it in your error handler.

> Even if I put my own onError() handler into my Application.cfc, I still get CB’s error handling.

That is because errors only bubble up this far if the actual framework errors out (or you rethrow it as the interceptor above shows). The Application.cfc’s onError() is basically a last-ditch effort to handle the error before it makes it to the CFML engine. It’s not an ideal location to deal with an error though since it’s outside of the framework’s life cycle and therefore not easily capable of running framework events, using logging facilities, or rendering views. It’s far more productive to catch and recover from errors while still inside the framework.

None of this explains why your ‘throw “exception0”;’ code does not appear to be executing though and I’m not sure how to help you there. Like I said in my previous E-mail, it works perfectly for me (exception is thrown and picked up by the framework so I can deal with it with a handler onError(), an onException interceptor, or an exceptionHandler, or a customErrorTemplate.) Perhaps you can zip up your sample app so we can try it.

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Short version:
I tracked the problem down: it’s a bug in CF9 & CF10. I shouldn’t imagine it’s a problem on Railo, but have not tested yet.

Long version:
[Is going on my blog, once I write it up]

Feedback from your response below:
You seem to not be quite getting what I’m saying, Brad. I’m all for frameworks providing functionality beyond simply acting as an MVC facilitator (which - really - is all frameworks are, with varying degrees of sugar added to them). And you’re dead right: this is all part of the value-addedness of using one framework over an other. Otherwise there’s only so many approaches one can take to handing MVC stuff, so there’d be no differentiators from one framework to another.

What I’m saying is that the functionality should be there to use, but out of the box the framework should do nothing. Anything it can do should not be being done until such time as the person developing their app with said framework goes “right, I’ll hook that in / switch that on / [whatever is necessary to make it work]”. Otherwise it’s all just bloat. Code should start small and grow bigger to accommodate actual requirements, not start of monolithic and leave a bunch of unnecessary overhead lying around.

The error handling is a good case in point. Standard industry practice with exceptions is to simply let them error until such point in time the person calling the code that errors goes “right; I’ll handle that now”. This is simply the way error-handling is done. Now I could understand if something goes amiss in the inner workings of CB then you might want to mask that by try/catching it, and then bubbling back a CB-specific exception instead of the underlying CF exception: all good. But all it should be doing is bubbling an exception back; not hiding the exception. That’s how exceptions are supposed to be dealt with.

However if there’s an error in my code (like me specifically doing a ), then you should leave it the hell alone and let it error. It should be up to me what gets done about this, not CB.

That said, I’m all good for CB to provide a mechanism for dealing with it (and, indeed, I expect it to), just like I’m fine with CF providing a mechanism for dealing with it. Or the web server providing a mechanism for dealing with it. But the thing is the mechanisms don’t interpose themselves by default: they just avail themselves should I decide to use them. This is how it should be done. It is the way that everything else does it, which should be a reasonable cue for you. I think it’s a bit “adolescent” of CB to ignore industry standard approaches to stuff and decide to do things its own way.

FWIW, I checked on Fusebox, Model-Glue, CFWheels and FW/1, and - by default - they all bubble back the exception, and return a 500 status code. FW/1 by default also outputs some of its own telemetry, but it also rethrows the original exception (this is a correct low-impact approach to a framework being “helpful” here: add value; don’t take anything away).

As for HTTP status codes, all I can say is you’re quite simply wrong that it’s desirable to - by default - subvert the intent of the HTTP protocol and return a “200 OK” in an error situation. A person’s browser might be configured to return “friendly” error messages. Indeed that might be the browser default (and it’s annoying as a developer, I know), but it is up to neither me as the application developer nor you as just the blimin’ framework provider to decide to override that behaviour. Again, cool if one has the misguided idea that returning an error screen with a “200 OK” status is sensible thing to do, and CB should not get in their way of doing that if they so choose. But it should not be the default behaviour.

End of griping (and, hey, it’s gonna come across more gripy than I mean it to; imagine it more as my side of a conversation at the pub, rather than a “written report of my findings” or something).

Short version:
I tracked the problem down: it’s a bug in CF9 & CF10. I shouldn’t imagine it’s a problem on Railo, but have not tested yet.

Long version:
[Is going on my blog, once I write it up]

Details: