Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at The Plaza Hotel 2012 (New York City) with:

Ask Ben: CFTry / CFCatch Issues

By Ben Nadel on

Someone contacted me the other day with a Try / Catch error. They were having problems with ColdFusion interacting with an Anti-Virus software. The AV software was putting locks on uploaded files which was causing ColdFusion to error out when it tried to access them. The programmer tried to handle this by using a Try / Catch code block, but was still getting errors. This is the snippet of code that I was sent:

  • <cfscript>
  • try {
  • fileRead = createObject( "java","java.io.FileInputStream" );
  • fileRead.init( theFile );
  • } catch (Any e) {
  • errorCode = '99';
  • };
  • fileRead.close();
  • </cfscript>

This code was causing a "java.io.FileInputStream" error. The problem is quite subtle and has to do with the line:

  • fileRead.close();

If you look at the Try / Catch block you will see that the fileRead variable creation is in the Try / Catch, but the fileRead.close() command is outside of the Try / Catch. This means that even though the variable fileRead might not contain a valid File object (if that is where the error occurs), the close() method is called no matter what.

To fix this, all we had to do was move the fileRead.close() to inside of the Try / Catch code block:

  • <cfscript>
  • try {
  • fileRead = createObject( "java","java.io.FileInputStream" );
  • fileRead.init( theFile );
  • fileRead.close();
  • } catch (Any e) {
  • errorCode = '99';
  • };
  • </cfscript>

Now, the fileRead.close() command only gets run if the fileRead variable contains a valid, initialized Java File object.

Tweet This Provocative thoughts by @BenNadel - Ask Ben: CFTry / CFCatch Issues Thanks my man — you rock the party that rocks the body!



Reader Comments

fileRead = createObject( "java","java.io.FileInputStream" );

try {
fileRead.init( theFile );

} catch (Any, e) {
errorCode = '99';
} finally {
fileRead.close();
};

No matter what happens the object will always be closed. With the code you wrote, if the fileRead.init throw an error, it will never make it to the close statement because the exception will be raised. Using finally, the exception is raise, but the object is still close because the finally statement is always executed even if an exception is raised or not.

If the catch clause did a rethrow, the finally would still be executed (which would not be true of code placed after the try/catch block).

Tony,

I gave a try to this code inside a CFscript

} catch (Any e) {
errorCode = '99';
} finally {
fileRead.close();
};

But it returns a syntax error on the finally line.... Is 'finally' part of coldFusion scripting language ? or is it pure Java/javascript? or I still miss something.... :)

@CP,

The thrown exception has information about the message and detail of the error. It also has the tag context so you can see what template and which lines of code have been executed. And, if you are particularly lost, it should also have the Java stack trace from which you might be able to take little pieces of information.

A CFFinally solution:

<cftry>
<!---- Do some work ---->
<cfcatch type="any">
</cfcatch>
</cftry>
<!--- <cffinally> --->
<!--- Do some clean up work --->
<!--- </cffinally> --->
<cfif IsDefined("cfcatch")>
<cfthrow object="#cfcatch#">
</cfif>

One thing to note is that if you encounter an exception during the clean up work you will end up loosing the original exception. You could place the cleanup code around a try catch and log the original exception before throwing the new one. Too bad you can't wrap exceptions around each other.