When calling a ColdFusion end-point from an Ajax call, the caller is expecting a certain format. In my projects, that's usually JSON. Regardless, it would be nice if the caller could assume a constant format, even for exceptions.

Typically, when an exception is generated in ColdFusion, the server auto-generates an HTML description of the exception. The assumption is that a developer or an end-user will be looking at the resulting HTML.

But in our case, the caller is a script, and parsing that HTML would be a chore. Instead, we can leverage ColdFusion's CFERROR tag to make sure that even exceptions generate valid JSON. Then, the caller can handle the exception data, possibly merging the information into the UI.

You can setup an exception handler for you JSON API calls as follows. You would typically include this on an individual API page, or in the Application.cfm above all your APIs.

<CFERROR type="exception" template="JSONExceptionSerializer.cfm">

Here is an example of how to handle the exception and format the results. You could also use a JSON library such as CFJSON or the tool that comes with CF8 to do the formatting.

<CFSETTING showdebugoutput="no" enablecfoutputonly="yes">

<CFHEADER statuscode="500" statustext="">

<CFCONTENT reset="true">
<CFOUTPUT>
    {
        error: {
            message: "#JSStringFormat(Error.message)#",
            template: "#Error.TagContext[1].template#",
            line: "#Error.TagContext[1].line#",
            type: "#Error.RootCause.type#",
            stacktrace: "#JSStringFormat(Error.StackTrace)#"
        }
    }
</CFOUTPUT>
<CFEXIT>
JSStringFormat() ensures that string content inside the JSON elements is properly escaped.

Extending this method, you can also manually throw exception in your ColdFusion code. For example, if the user is not logged in on the back-end, instead of doing this:

<CFOUTPUT>Error: not logged in!</CFOUTPUT>
<CFEXIT>
You can simply throw an exception.
<CFTHROW message="Not logged in!">