ColdFusion Muse

Building a Robust Error Handler

If you have been around the ColdFusion world as long as the Muse you have heard of Mary Jo Sminkey. Mary Jo built a popular ColdFusion ecommerce platform called CFWebstore. She has vast experience in ColdFusion and a seemingly boundless fountain of energy. Her eclectic interests range from technology to baking to dog training. As far as CF Webtools and the Muse can tell, Mary Jo excels at everything she does. We frankly suspect she is actually twins or triplets pretending to be only one person :) The following article is by Mary Jo and details her approach to application specific error handling. She has a detailed and thorough knowledge of the topic. Using this approach she has been able to reduce the number of errors on a very high traffic E-commerce site to practically nil. In the first of 2 articles MJ (as we call her with great affection) details the structure and usage of the handler.

Building a Robust Error Handler (by Mary Jo Sminkey)

Let's face it, sometimes we put less effort into the error handler than into the rest of our code. We might put something in place that throws up a "user friendly" page, and maybe email a dump of the catch or error structure, but when the site goes live, and we are deluged with errors due to search bots, hack attempts and poorly coded pages we turn it off or send all those emails to a seldom-visited mailbox. Sometimes we implement error handling as cftry/cfcatch blocks that do little more than preventing errors from being thrown, instead of helping us track down the issue.

I look at the error handler as a way to help make a site as bug-free as possible. By having it email me as much information as possible about errors, I troubleshoot, fix and patch, and get to a point where errors are the exception rather than the rule. In this article, we'll look at building a single-page, comprehensive error handler. In a future article, we'll look at integrating that error handler with the open source bug tracker BugLogHQ. Before we begin with our error handler let's talk about our error handling strategy.

[More]

Setting Timeout Successfully on a Web Service Call

One of the annoying things about ColdFusion (yes even the Muse gets annoyed) is the sort of haphazard way it deals with timeouts. If the process you are timing out involves a call to an external service it's really a crap shoot whether or not it will work. Once CF hands off to the external service and starts its vigil waiting for the callback, the timeout value is largely ignored. Don't believe me? Create a long query to a DB Server and then pull the network cable while the query is running. The thread will usually continue to hang even if you have added a timeout value.

Recently Super Guru Jared Riley (Computer Services Inc. (CSI)) was lamenting this very problem with regard to a web service he was using. Because the web service would sometimes hang at the other end due to reliability issues his server was accumulating dormant ColdFusion threads which eventually would fill up the simultaneous request pool and begin to queue all other requests - effectively locking up the server.

It turns out a savvy developer named Jeff Nelson (also of CSI) came up with a solution for this particular issue. Before I share I must warn my readers that this is an undocumented solution that sets an underlying AXIS property. That means that subsequent changes to some future version of the underlying Axis libraries could cause this to error out at some point. The Muse has been known to use undocumented features successfully from time to time - but it pays to be vigilant when upgrading or patching. Also keep in mind this is only for web services. It will do nothing for Queries or cfmail etc. With that in mind here is the "fix".

Setting the timeout axis property

<cfset webservice =
createObject('webservice', 'http://exampledomain.com/webservice.cfc?wsdl') /
>

<cfset webservice._setProperty("axis.connection.timeout",
                        javaCast("int",10000)) /
>

Now some of you might immediately say "hmmmm.... that's the connection timeout, but it doesn't really cover long running requests that occur AFTER the connection is made does it?" Jared has actually done a good bit of testing and claims that this property will timeout a request for either a connection reason or a time of process reason.

So if you are trying to solve this particular problem this might be an appropriate course of action. Now if we could just find similar settings for various DB Drivers my life would be complete.

Follow Up

For those of you who want to remind me that there already is a timeout property to cfinvoke that can be used here I would respond that that setting works correctly for creating the stub classes. In other words if ColdFusion can't compile the WSDL with the time alloted it will timeout. But it doesn't work for actual calls to the methods instantiated.

Performance Tip - CF Builder 2 Plugin on Windows 7 64 bit

The Muse is a slow moving tools user. I just switched to CF Builder about a year ago in fact. Before that I was using CF Eclipse. I still use the venerable Homesite for quick troubleshooting on production servers or to review code. I'm using it to write this blog in fact. I have written my blogs in hand coded HTML for many years - which I'm sure, explains the copious amounts of in-line CSS throughout. But I'm a full convert to CF Builder now and have been for some time. All my "Code-for-production" work is done using CFB with integrated SVN through a local environment. Recently on one of the email lists I follow I heard a tip from mad-genius Kevin Miller (Websolete.com).

Like the Muse, Kevin runs CF Builder 2 on Windows 7 64bit as a plugin against a heavily customized version of eclipse 64bit. Also like the Muse he finds it to be an underachiever. CFB (or perhaps it's just 64bit Eclipse and we are throwing CFB in there unnecessarily) tends to use way more processor than seems necessary and at times seem to lag and catch up like a fat man at a marathon. On rare occasions when I'm editing large files or (in particular) browsing files on the network it simply peters out and needs to be defibrillated - also like the fat man I suppose. Of course I have edited the eclipse.ini file and I run a large heap. I've experimented with different GC's and other params. In the end I just kind of assumed that.... well that it was a dog like many Java desktop apps (don't judge me). And at age 46 I've learned to settle for a lot of things, so I was reasonably content to simply live with it. I know - it sounds horrible when I write it down like that (doh!).

But Kevin suggested switching from javaw.exe to the jvm.dll by adding the "-vm" switch. I had assumed that "javaw.exe" was necessary because it builds a Windows GUI. But that "GUI" is not the Eclipse gui (at least I don't think so). More likely it is that annoying system tray thingy that keeps begging me to let it spout all the wonderful things Oracle is doing while it upgrades my SDK. Anyway, with a little trial and error I found that Eclipse runs splendidly using the jvm.dll and I'm having fewer lags and problems with. Kevin's post is here if you want the full story. Let me add to his comments that I had a bit of trouble finding the right "jvm.dll". The first one I tried was apparently 32 bit. The one I needed was in the jre6 folder - which eventually I found installed elswhere on my machine. Thinking back I think the SDK install does ask for a specific location for those files - so that makes sense.

Once I had right path I opened my eclipse short cut and added..

eclipse.exe -vm "C:\Program Files\Java\jre6\bin\server\jvm.dll"

...to the target area so that I'm using it each time I open eclipse. Note the necessary quotes around the path. They are needed because of the space in "program files". As always I count on my readers to add to the conversation - just be nice. Remember I grew up on Andy Griffith, not South Park. So let's leave Kenny alone on this post. On the other hand Aunt Bee is fair game.

Good Developers Practice Safe Query Caching

First let me say that query caching on a CF server is not a panacea. There are many ways to improve performance and there are many techniques for caching. All techniques have trade-offs. Still, there are instances where caching will save you time and money - and those are both things in short supply. More to the point, query caching is so easy to implement that it can be done for an entire site or application in a relatively short time - as long as you follow some simple rules and take some precautions (please people - use "safe caching").

[More]

MS Throws a Curve: IE 8 and the New Security Message

You have probably seen the special security warning that appears when a page has "a mix" of secure and not secure resources. I recently ran into a usability issue with regard to this message that I thought deserved a quick post on the Muse. Let's start with an example:

[More]

The Boolean-O-Matic: ColdFusion's Weird Relationship With Truth

Hello muse readers. I apologize for my long hiatus (which means a stretch of time where I was absent - it's not a size joke).  I have been swamped with closing out the old year and implementing plans for the new year. I'm afraid our little chats were put on the back burner temporarily. However, now that new year has begun I am committed to continuing our friendship. I'd like to start out with something simple. Indeed, some of you may find this to be ColdFusion 101.

This post is going to discuss Boolean values. A Boolean is one of those datatypes more defined by how it is evaluated than by what it contains. The muse definition is that if something can return a "true" or "false" in the context of a logic statement (cfif) it is a Boolean. It may be other things as well, but it has the properties of a boolean and returns one of 2 states - true or false. Interestingly, every language handles Booleans differently and many of them use the same wild west sort of approach that ColdFusion uses - where several things can be used as Booleans.

Even if you don't know it, you use Booleans every time you create a cfif statement. Still, it's surprising how many advanced developers do not fully grasp all the ways that ColdFusion has of evaluating something as True or False. And having said that I am fully aware that some smarty-pants developer will immediately inform me of some new way I haven't seen before of evaluating true or false (thank you sir, may I have another).

Anyway, I'd like to take a little journey into the world of Booleans to start off my 2010 blogging. Note: this post has a number of neat "tips and tricks" that you may have not seen before. Whether you choose to use them can depend greatly on your environment, the structure of your code and the standard you are using (especially in a team environment). I'm not advocating for or against, although I have my own preferences. I'm only putting it out there as another arrow in your quiver. So with that caveat taken care of, let's begin.

[More]

Interesting Mail Headers

My good friend Jake Churchill was surfing dev shed and he found this post regarding cfmail. The question is pretty easy, but one of the comments further down caught his eye. A user named mackindlays makes the statement that "Many mail services bounce CF generated mails now". Personally I do not believe there is any evidence that mail servers bounce CF generated mail any more than .NET generated mail or PHP generated mail etc. Perhaps mail servers score mail that is obviously sent from a web server as "more likely to be spam". Certainly that was a contention of my previous post on the subject. At any rate, his solution was to spoof the mail headers for Microsoft Exchange using CFMAILPARAM.

<cfmailparam name="X-MimeOLE" value="Produced By Microsoft Exchange V6.5.7226.0">
<cfmailparam name="X-MS-Has-Attach" value="yes">
<cfmailparam name="X-MS-TNEF-Correlator" value="">
<cfmailparam name="Content-class" value="urn">
<cfmailparam name="content-classes" value="message">
I have no idea if this will work or be successful (I'll let my readers know what I find out). But this rather un-muse like solution is perhaps one more arrow in the quiver of folks trying to send legitimate email.

Solving an Email Send Problem: a Simple, Innovative Approach

Getting email to go through for your customer or newsletter can be tricky these days. An email has to work pretty hard to make it through all the barriers in its way. The problem is compounded when you have an automated email system like a newsletter or marketing apparatus. Even if you follow all the rules you may still achieve a marginal success rate. One of our customers (Tom Long of digbro.com) has a unique system for marketing that is clearly not spam. It involves users sending individual emails out to customers with whom they already have a relationship. It's not bulk email and there are clear opt out instructions. The email goes out in a small trickle of a few hundred an hour. The system tracks the lead internally and an elaborate reporting system allows the user to figure out success rates, run referral programs and keep track of the customer information.

In spite of the benign nature of this system it has still been difficult getting emails out to some domains - particularly large email domains like Yahoo and Hotmail. We have done some innovative things like creating a "scoring" system that utilizes calls to spam assassin to try and "rate" the email before it is sent. The user submits his email text, the system dummies up an email, pipes it to Spam Assassin, retrieves it back and extracts the score - all before the email is sent. Pretty nifty - but not a panacea. In spite of our best efforts the success rate to known good email addresses on larger email domains improved only marginally. This customer is one of those visionary men that simply can't help thinking outside the box. Check out his solution.

[More]

Interesting Loop for Dates and Times

Now my readers know that I've seen enough Coldfusion code in my day that I can quote some livedoc articles verbatim (including the notes and comments). It takes a great deal to surprise me with something new. But here's a snippet I found the other day that made me sit up and take notice. The fact that it uses CFLOOP (one of the most ho-hum of all the CF tags) is even more surprising. This is a loop that iterates over time increments. You can use it to create incremental time objects that are n number of minutes or seconds apart. It doesn't look like you might expect either. Here is an example that loops from 8 to 5 in 45 minute intervals:

[More]

Viewing All Scopes for a Request

This little gem makes me giddy all over - and I don't get giddy easily. There was that one time at a Bette Midler concert in ‘99.... but I digress. Here's a method you may find useful during development, debugging and possibly for error handling. It's a method of the getPageContext() function that returns all scopes available to the request. That would be:

  • Variables
  • Form
  • Cffile
  • cfthread
  • Request
  • Server
  • Http
  • Cgi
  • Client
  • URL
  • Session
  • Cookie
  • File
  • Application
This tag does you a favor in that it guarantees that the scope will be there. So you don't have to "test" for session and then dump out or handle session. It will just show up for you. Here's the code:

[More]

Adding Cfqueryparams to a Legacy Site Without Losing Your Hair

So you got hit with the latest SQLi attack eh? SQLi is the hip acronym for "sql injection" that fancy pants security people use. You've put in some stop gap measures and now you are slogging through 3000 queries trying to add cfqueryparam to everything. It's a laborious task to be sure. Here are some special tips from the muse that might help shorten it.

[More]

Portable ColdfFusion Code (Linux and Windows)

I'm a big fan of ColdFusion on Linux. Not that I know half as much about Linux as I do about Windows. Still, we have a good number of Linux servers here at CF Webtools and CF Linux Guru Ryan Stille keeps them all humming a happy tune. I think both platforms have advantages. If you have ever tried to write ColdFusion code that is able to run on both Linux and Windows you will know there a few differences. One difference is case sensitivity for file names.

On windows if you include a file called "myfile.cfm with a cfinclude that is something like <cfinclude template="myFile.cfm"> it will work just fine. Move the same code to Linux and it will generate a "File Not Found" error because of the capital "F" in your include statement. The good news is that once you fix this problem on Linux you can move it back to Windows and it will now work on both platforms. The other common problem is a bit more challenging. It has to do with file paths.

[More]

Var Scoper Tool

Mike Henke reminded me of this slick little tool called varscoper. Pass in a directory and it will ferret out all the places where variables are not correctly scoped. For example, it will sshow where you have not correctly var'ed variables in a function. The project was produced by Mike Schierberl who's blog has some excellent goodies and tips.

varscoper won't catch the cfhttp scope, but it would catch a variable declared as a result attribute. Either way, it could save you some headaches - especially when dealing with a large pool of code, or taking over someone else's code.

Threads Not Terminating on ColdFusion 8.0.0

Over the past few days on CF Talk Ian Skinner has been struggling tuning an application that makes use of CFTHREAD. In his application a process spawns threads for creating report files. Ian Reports that the process would spawn the threads, but the threads themselves would neither complete gracefully nor respond to a "terminate" action (<cfthread action="terminate" ...>). No suggestions from the muse or anyone else seemed to help. Finally he upgraded to ColdFusion 8.0.1 and the problem appears to be resolved. Threads complete gracefully without hanging around.

Nothing in the 8.0.1 release notes raises any red flags with me that would indicate why updated to 8.0.1 resolved the issue. I suspect that something very specific about his JVM was causing it. Still, it's nice to know if you run into this ticklish issue there is a way around it.

CFCs, the Variables Scope, and the Application Scope

It's pretty common to use the application scope to cache components. If your component is a collection of methods or data access functions it's often faster to put them into the application scope than it is to create an instance with each request. Now you probably know that you should quality all of the variables in a function with the "var" key word. This insures that the variable exists inside the "scope" of the function call. This allows multiple function calls to be made to the same instance without one set of variables over writing the other.

One of the areas where this can be difficult to manage is when using a ColdFusion tag that creates its own scope. Take CFHTTP as an example.

[More]

More Entries




Blog provided and hosted by CF Webtools. Blog Sofware by Ray Camden.