RE: cferror causing me pain

2003-12-10 Thread Barney Boisvert
This is 100% opinion, but CFERROR should be a last ditch effort to make sure
no error messages appear on the screen.You should always use one, but all
your actual error trapping should be done with CFTRY..CFCATCH if at all
possible.

If you're using something like Fusebox or Mach-ii, it's a snap, because
everything goes through a single template (index.cfm) before being delegated
to one of the various request handlers.Just put your CFTRY..CFCATCH in
there.If you've got a normal app, where each page is it's own template,
then you're kind of stuck, unfortunately, although you can come close to
duplicating by doing something like this in every template:

cftry
!--- all template content goes here ---
cfcatch type=any
cfinclude template=/error/errordispatcher.cfm /
/cfcatch
/cftry

Then in errordispatcher.cfm you can use the CFCATCH variables to determine
what to do (different error types), and you still have full access to all
the CF tags you could ever want.

That won't handle 404s and such, so in your actual CFERROR template, I
usually use a client-side redirect to forward back to my application, to an
error page, so I can once again use all the CF tags.You need to be careful
with that page though, because you could end up in an infinite loop.It HAS
to be defined, and it should only use CF, no external resources at all (DB,
web services, network shares, etc), because that might be the base cause of
the error.

Bottom line, the CFERROR templates should be as dumb as possible, becase, as
you've seen, they are so devoid of function to be almost worthless.

Cheers,
barneyb

 -Original Message-
 From: Pete Ruckelshaus [mailto:[EMAIL PROTECTED] 
 Sent: Wednesday, December 10, 2003 11:11 AM
 To: CF-Talk
 Subject: cferror causing me pain
 
 CF MX 6.1/Windows XP
 
 I'm trying to implement some site-wide error handling using 
 cferror, and 
 it's really being a PITA.
 
 In my application.cfm file, at the very end, I have:
 
 cferror type=EXCEPTION template=/error/error.cfm exception=ANY
 cferror type=REQUEST template=/error/404.cfm
 
 error.cfm and 404.cfm are both in /error/, I have verified 
 this.After 
 I made this change, I restarted services and then loaded a test page 
 with an error in it.Instead, I got the standard exception error 
 handling page (not my page).After about 30 minutes of 
 screwing around, 
 I went into CFAdmin and registered /error/error.cfm as the 
 default error 
 handler, and lo and behold, it worked.I then went in and 
 removed that 
 setting from CFAdmin and it still worked.Has anyone else seen this 
 behavior?
 
 Second problem is the request error page, /error/404.cfm
 That page is 
 being loaded as expected when I force a request error, but I 
 cannot for 
 the life of me get the error variables to display as they 
 should.It is 
 my understanding from 
 http://livedocs.macromedia.com/coldfusion/6.1/htmldocs/tags-p2
 4.htm#wp2022557 
 that I can display a number of variables, but cannot 
 otherwise use any 
 CF tags.Well, here is /error/404.cfm, and it doesn't 
 display the value 
 for error.browser (it displays #error.browser# like it's expecting a 
 cfoutput tag):
 
 !DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN
 html
 head
 	titleUntitled/title
 /head
 body
 h1404/h1
 #error.browser#
 /body
 /html
 
 
 When I do put #error.browser# inside cfoutput tags, it throws 
 an error.
 
 What am I doing wrong?All I want to be able to do is display a form 
 that will allow the end user to submit feedback, and part of 
 that form 
 will be these error variables in hidden form fields.
 
 Thanks,
 
 Pete
 
 

 [Todays Threads] 
 [This Message] 
 [Subscription] 
 [Fast Unsubscribe] 
 [User Settings]




RE: cferror causing me pain

2003-12-10 Thread Dave Watts
 I'm trying to implement some site-wide error handling using 
 cferror, and it's really being a PITA.
 
 In my application.cfm file, at the very end, I have:
 
 cferror type=EXCEPTION template=/error/error.cfm exception=ANY
 cferror type=REQUEST template=/error/404.cfm
 
 error.cfm and 404.cfm are both in /error/, I have verified 
 this. After I made this change, I restarted services and then 
 loaded a test page with an error in it. Instead, I got the 
 standard exception error handling page (not my page). After 
 about 30 minutes of screwing around, I went into CFAdmin and 
 registered /error/error.cfm as the default error handler, and 
 lo and behold, it worked. I then went in and removed that 
 setting from CFAdmin and it still worked. Has anyone else seen 
 this behavior?

No, I haven't seen that specific behavior. I have seen all sorts of odd
behavior that was only resolved after restarting the CF service, oddly
enough. It's worth pointing out that CFERROR TYPE=EXCEPTION won't catch
every possible error, only things that CF considers to be runtime
exceptions.

I assume that you have a directory called error in your web root, and that
you have the root slash / mapped in CF to your web root, or that you have
a CF mapping called /error pointing to your error directory? If I recall
correctly, the CFERROR tags resolve their paths the same way that CFINCLUDE
and CFMODULE do.

 Second problem is the request error page, /error/404.cfm
 That page is being loaded as expected when I force a request 
 error, but I cannot for the life of me get the error variables 
 to display as they should. It is my understanding from 
 http://livedocs.macromedia.com/coldfusion/6.1/htmldocs/tags-p2
 4.htm#wp2022557 that I can display a number of variables, but 
 cannot otherwise use any CF tags.

That is also my understanding, and has been my experience. I've never had an
error page with a name that consists of a number; perhaps that's the
problem. (This is purely a shot in the dark.)

Dave Watts, CTO, Fig Leaf Software
http://www.figleaf.com/
voice: (202) 797-5496
fax: (202) 797-5444
 [Todays Threads] 
 [This Message] 
 [Subscription] 
 [Fast Unsubscribe] 
 [User Settings]




RE: cferror causing me pain

2003-12-10 Thread Dave Watts
 This is 100% opinion, but CFERROR should be a last ditch 
 effort to make sure no error messages appear on the screen.
 You should always use one, but all your actual error trapping 
 should be done with CFTRY..CFCATCH if at all possible.

I would strongly disagree with this (not that my opinion is any better than
yours!)

I run into a lot of people using CFTRY/CFCATCH around their entire page, and
I think it's a waste. I'd strongly recommend reserving the use of CFTRY and
CFCATCH for situations where you have an expected problem with a specific
algorithm, and a specific solution for that problem.

 If you're using something like Fusebox or Mach-ii, it's a 
 snap, because everything goes through a single template (index.cfm) 
 before being delegated to one of the various request handlers.
 Just put your CFTRY..CFCATCH in there. If you've got a normal 
 app, where each page is it's own template, then you're kind of 
 stuck, unfortunately, although you can come close to duplicating
 by doing something like this in every template:
 
 cftry
 !--- all template content goes here ---
 cfcatch type=any
cfinclude template=/error/errordispatcher.cfm /
 /cfcatch
 /cftry
 
 Then in errordispatcher.cfm you can use the CFCATCH 
 variables to determine what to do (different error types), and 
 you still have full access to all the CF tags you could ever 
 want.

You have full access to all CF tags using CFERROR TYPE=EXCEPTION, CFERROR
TYPE=MONITOR, and the site-wide error handler. Given that, what's the
advantage to using CFTRY in this case?

 That won't handle 404s and such, so in your actual CFERROR 
 template, I usually use a client-side redirect to forward back
 to my application, to an error page, so I can once again use 
 all the CF tags. You need to be careful with that page though, 
 because you could end up in an infinite loop. It HAS to be 
 defined, and it should only use CF, no external resources at 
 all (DB, web services, network shares, etc), because that might 
 be the base cause of the error.

In general, I'd agree with this part - your CF error handlers have to be
careful not to trigger an error. However, if you use the site-wide error
handler, or CFERROR TYPE=EXCEPTION, and your error handling page has an
error, it won't trigger an infinite loop, but will instead throw to the
built-in CF error handler and you'll get the big white error page we all
know and love. However, if you do the redirect that you're talking about,
you may well get in an infinite loop.

 Bottom line, the CFERROR templates should be as dumb as 
 possible, becase, as you've seen, they are so devoid of 
 function to be almost worthless.

This used to be true, but I don't think it is true at all any more. I find
CFERROR and the site-wide error handler to be immensely useful.

Dave Watts, CTO, Fig Leaf Software
http://www.figleaf.com/
voice: (202) 797-5496
fax: (202) 797-5444
 [Todays Threads] 
 [This Message] 
 [Subscription] 
 [Fast Unsubscribe] 
 [User Settings]




Re: cferror causing me pain

2003-12-10 Thread Adam Churvis
 This is 100% opinion, but CFERROR should be a last ditch effort to make
sure
 no error messages appear on the screen.You should always use one, but
all
 your actual error trapping should be done with CFTRY..CFCATCH if at all
 possible.

This goes against the whole idea of how exception handling should be
structured in an application.For a diagrammed explanation of the three
tiers of structured exception handling, see page 430 of The ColdFusion MX
Bible.If you don't have a copy, here's an explanation that might help.

Envision a framework that has three layers...

The top layer contains one or more sieves that CFCATCH exceptions thrown by
your application.Each sieve catches a specific type of exception
(type=Database, type=_expression_, etc) that you expect might reasonably
occur in your application, such as a unique index violation on an alternate
key column that would be thrown by the database if someone tried to register
twice using the same email address.

This is a fairly coarse test, so you would further test inside the CFCATCH
construct for the NativeErrorCode that applies to the specific
type=Database exception you want to handle.If the exception is the one
you want to handle in an exceptional manner, the code inside your CFCATCH
type=Database construct would take over and handle it.If it was some
other type=Database exception, you would CFRETHROW the exception you
caught back out of the top layer, down to the second layer in the
exception handling framework.

If an exception isn't handled by the top layer of CFCATCH constructs -- 
either by not having a CFCATCH of the type that was thrown, or by catching
and then RETHROWing the exception -- then it becomes a bona fide error.I
know that exceptions and errors are thought of as the same thing, but it
sometimes helps to conceptually separate them in your mind this way, where
exceptions result in handling the flow of work in some exceptional manner
(not just displaying a more friendly error message), and errors are
exceptions that stop the flow of work because there is no exceptional
process to follow when them occur.

One indication that your exception handling top layer might be doing the
wrong job is if more often than not you specify type=Any or altogether
omit the type attribute from CFCATCH.If you are doing this most of the
time then you're probably using CFTRY to improperly perform CFERROR's job,
which is the second layer in the exception handling framework.

The second layer contains one or more sieves that handle errors.Each sieve
corresponds to a specific error handler -- either an error handling template
installed via CFERROR or a CFCASE construct that tests for exception type
inside a multi-use error handling template -- and typically logs the error,
displays a friendly error message, and possibly emails the developer.

If an error handler for the specific type of error thrown wasn't installed
via CFERROR, then that error falls through to the site-wide error handler,
which is the third layer of the exception handling framework, and is more
like a solid-bottomed catch basin in this metaphor.I refer to these as
crashes because they should typically have been handled by an error
handler, and often suggests a more serious problem.

Setting up a structured exception handling framework like this enables you
to really leverage ColdFusion's exception handling capabilities.Take for
example the guy who tries to register twice on your website.Are you first
SELECTing from the user table based on his email address, checking the
RecordCount, and then conditionally INSERTing only if RecordCount EQ 0?
With properly structured exception handling, you simply attempt the INSERT
inside a CFTRY with a CFCATCH type=Database that further tests
CFCATCH.NativeErrorCode for a value of 2601 (unique index violation on SQL
Server), then re-route the user to a page that not only describes exactly
what's going on, but also gives him an interface for emailing his password
to himself.An exceptional process flow for a specifically-handled
exception.

Another benefit is that you can use CFTHROW to nicely integrate your own
business logic into the same exception handling mechanism used by
ColdFusion's own exceptions.If your business rules define certain
anomalies as exceptions, even if those anomalies don't throw exceptions in
ColdFusion, you can throw a custom exception via CFTHROW and let your
structured exception handling framework kick in and do whatever is
necessary.Using dot notation in the values of your type attributes
(type=BusinessRules.Inventory.UnderLimit) enables you to do some pretty
fancy things, but that's another discussion altogether.

We spend a good bit of time teaching proper structured exception handling in
our ColdFusion MX Master Class because it really does make applications
easier to design, build, and maintain, and you don't end up writing
unnecessary and burdensome database queries and kludgey ColdFusion routines
to do something that's already