6

I am using ColdFusion 8. I would like to catch a NoClassDefFoundError exception in ColdFusion however I can't... It still fails and logs the error in the exception.log file. Here is what I tried.

<cftry>
    <cfset myJavaObject.myMethod()>
    <cfcatch type="any">
        <cfdump var="#cfcatch #">
    </cfcatch>
    <cfcatch type="java.lang.Throwable">
        Horrible exception.
        <cfdump var="#cfcatch #">
    </cfcatch>
</cftry>

But this does not work. Could you please show me how to do that? I need to catch this error at a particular place and not in the OnError function of my Application.cfc.

Miguel-F
  • 13,450
  • 6
  • 38
  • 63
Abbadon
  • 2,513
  • 3
  • 25
  • 33
  • `NoClassDefFoundError` is an unchecked exception, are you sure ColdFusion catches those? – fge Jan 09 '13 at 14:20
  • I have added the `ColdFusion` tag to your question so more people will see it. You have a couple of typos in that code example. The ending `cftry` and there should not be any spaces between the pound-signs and the variable name, `#cfcatch#`. The catch type of 'any' should get the error, not sure about the 'java.lang.Throwable' type? – Miguel-F Jan 09 '13 at 15:20
  • 1
    if you have any errors in your catch it will throw the CF error. as Miguel-F said, if those spaces exist in your code it is a syntax error and CF is reacting correctly. the error handlers have to be perfect or they are essentially useless. – genericHCU Jan 09 '13 at 15:38
  • I found this similar post regarding CF 8 - [ not 'catching' an error](http://stackoverflow.com/questions/4855110/cfcatch-not-catching-an-error). See the answer below from @Leigh. Try that. – Miguel-F Jan 09 '13 at 15:45
  • @Leigh is SO acting up or did you delete your answer? I don't see it anymore. – genericHCU Jan 09 '13 at 16:57
  • @Travis - I deleted my answer as it is wrong. I was mistakenly testing with the ClassNotFound instead of NoClassDefFound. Not enough coffee, duh! – Leigh Jan 09 '13 at 16:58
  • @Leigh didn't you test good with 'any'? – genericHCU Jan 09 '13 at 17:01
  • Yep, but it only worked because ClassNotFound is an `Exception`, not an `Error` like NoClassDefFound. (So it did not really work) In CF10, Application.onError seems to catch the `Error`. Need to do some more testing though. – Leigh Jan 09 '13 at 17:05
  • @Abbadon - Re *I need to catch this error at a particular place* First I would ask *why*? `NoClassDefFound` suggests a configuration problem which is not something you normally encounter in a production environment. Nor it is not something you can "fix" at runtime. So can you elaborate on what you are trying to do and why? Unfortunately, given that `cfcatch` does not handle `java.lang.Error`'s, that leaves general error handlers. If those are out, that is pretty much the ball game afaik .. – Leigh Jan 09 '13 at 23:18
  • @Leigh I must catch the exception to log in database. The problem was that I could not change the Application.cfm to an Application.cfc to implement the onError function. What's strange is that according to Coldfusion documentation it is possible to catch java Errors. "Note: The Any type includes all error with the Java object type of java.lang.Exception. It does not include java.lang.Throwable errors. To catch Throwable errors, specify java.lang.Throwable in the cfcatch tag type attribute." (http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=Errors_05.html) – Abbadon Jan 16 '13 at 12:39
  • Just to follow up, the documentation is wrong (or there is bug). `cfcatch` does not catch java.lang.Error's. If you are stuck with `Application.cfm`, try using ``. – Leigh Jan 17 '13 at 19:12

1 Answers1

9

Now that I have had more coffee, I do not think cfcatch is capable of catching a NoClassDefFoundError. According to the documentation, it only processes Exceptions:

Exceptions are events that disrupt the normal flow of instructions in a ColdFusion page, such as failed database operations, missing include files, and developer-specified events.

NoClassDefFoundError is an Error.

An Error indicates serious problems that a reasonable application should not try to catch

It sounds like cfcatch was only designed to handle normal "recoverable" problems. There is really not much you can do once you get a NoClassDefFoundError. It is a severe error and you cannot get past it (under normal circumstances). The most you can do is show an error message and exit.

Application.onError seems to handle uncaught Errors like NoClassDefFoundError, as well as Exceptions. So I think the best you can do is implement onError and have it display an error page.

    <!---- test code --->
    <cfset myJavaObject = createObject("java", "path.to.MyClass") />
    <cfset myJavaObject.myMethod() />

    <!---- Application.cfc --->
    <cfcomponent>
         .... settings ...
         <cffunction name="onError" returnType="void"> 
             <cfargument name="Exception" required="true" /> 
             <cfargument name="EventName" type="string" required="true" /> 
             <h1>onError Test</h1>
             <cfdump var="#Exception#" />
         </cffunction>
    </cfcomponent>

    // test class
    public class MyClass {
        public void myMethod() {
            throw new NoClassDefFoundError ("Testing...");
        }
    }

Update

The Any type includes all error with the Java object type of java.lang.Exception. It does not include java.lang.Throwable errors. To catch Throwable errors, specify java.lang.Throwable in the cfcatch tag type attribute

Despite what the documentation says, catching Throwable does not work in any of my tests (or yours). That strongly suggests a bug in the behavior or the documentation. Either way it does not work as advertised, so as mentioned above, the only alternative I know of is using a general error handler. If you must stick with an Application.cfm file for some reason, try using <cferror type="exception" ...>

(Absurd) Test case:

<cftry>
   <cfset myJavaObject = createObject("java", "path.to.MyClass")>
   <cfset myJavaObject.myMethod()>
   <cfcatch type="java.lang.NoClassDefFoundError">
      CAUGHT java.lang.NoClassDefFoundError
   </cfcatch>
   <cfcatch type="java.lang.LinkageError">
      CAUGHT java.lang.LinkageError
   </cfcatch>
   <cfcatch type="java.lang.Error">
      CAUGHT java.lang.Error
   </cfcatch>
   <cfcatch type="java.lang.Throwable">
      CAUGHT java.lang.Throwable 
   </cfcatch>
   <cfcatch type="any">
      CAUGHT ANY
   </cfcatch>
   <cfcatch>
      CAUGHT
   </cfcatch>
</cftry>
Leigh
  • 28,765
  • 10
  • 55
  • 103
  • +1 This is the same conclusion that they came to in the other question that I referenced (in the comments). I don't even think the OP is paying attention any more... – Miguel-F Jan 09 '13 at 19:04
  • Yep, I was on that thread too. Totally forgot `cfcatch` would not help until I had the rest of my coffee, then thought "duh!" – Leigh Jan 09 '13 at 19:21
  • I can't accept this answer according to Coldfusion documentation : The Any type includes all error with the Java object type of java.lang.Exception. It does not include java.lang.Throwable errors. To catch Throwable errors, specify java.lang.Throwable in the cfcatch tag type attribute. (http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=Errors_05.html) – Abbadon Jan 16 '13 at 12:40
  • @Abbadon - Sadly it would not be the first error in the documentation... That said - I do not recall all of the tests I ran last week. But if it did not work for you, that suggests it could just be be a documentation error. I will re-run my tests later (with CF8) and see what I turn up. – Leigh Jan 16 '13 at 16:53
  • @Abbadon - I re-ran my tests and am pretty sure the documentation is wrong. See my updated response above. – Leigh Jan 17 '13 at 16:59
  • @Leigh since your response seems now fully complete I will accept it! Thanks for this in depth review :). – Abbadon Jan 23 '13 at 08:52