This article will show you how to implement extensive server-side error handling with ColdFusion and JSON. Although not necessary, we will leverage the Kendo UI Extended Message Boxes API to provide notifications to the user.

In this example, we will use Ajax on the client to invoke a ColdFusion function on the server that is used to handle our database transactions. This function will act as a process gateway to invoke other server-side processes. If the process is successful, the function will return a success message or return any errors back to the client as a structure.


Client Side invokeSproc Function

The following JavaScript code on the client is used to invoke the invokeSproc function on the server using Ajax. Both the client and server functions are named invokeSproc in order to associate the logic between the client and server. This is a generic function that passes in a processId to determine what Stored Procedure or other server side function to run. After successfully invoking a stored procedure on the server, the function is using the checkProcess callback function to determine if the process has been successfully run.


function invokeSproc(sprocName, processId, optionalArgumentList){
        // Submit form via AJAX.
        $.ajax(
            {
                type: "get",
                url: "subLedger.cfc?method=invokeSproc",
                data: {
                    sprocName: sprocName,
                    userId: <cfoutput>#getUserId()#</cfoutput>,
                    processId: processId,
                    optionalArgumentList: optionalArgumentList
                    },
                dataType: "json",
                cache: false,
                success: function(data) {
                    checkProcess(data, sprocName, processId);
                }
            }
        );
    }

Server-Side InvokeSproc Function

The invokeSproc function on the server is responsible to perform all the database transactions. This server-side function takes the arguments sent by the client to perform database transactions and to invoke SSIS packages for data transformation. For error handling, this function sets the sprocSuccess and dbError vars and implicitly creating an empty response ColdFusion structure that we will use to send back messages to the client when there are errors.


<cffunction access="remote" name="invokeSproc" returnformat="json" displayname="invokeSproc" hint="This method will call a stored procedure written by the database group that calls a package, or run another stored procedure that launches an executable, or a series of external executables.>
        
    <cfargument name="sprocName" type="string" required="no" default="" hint="Used for functions that used the original processes. No longer needed for recent processes.">
    <!--- The userId is passed in when posting --->
    <cfargument name="userId" type="numeric" required="no" default="0" hint="Provide the user_id of the logged in user.">
    <cfargument name="processId" type="string" required="no" default="" hint="The processId may be chainable, that is, we can run a sequence of processes in order. If the processId is chained, it will have two or more processId's separated by comma's.">
    <!--- Handle optional arguments. --->
    <cfargument name="optionalArgumentList" type="string" required="no" default="" hint="Allows the developer to pass in additional arguments ">
    
    
    <cfparam name="sprocSuccess" default="true" type="boolean">
    <cfparam name="dbError" default="" type="string">
    
    <!--- Prepare the default response object. --->
    <cfset response = {} />
    <cfset response[ "dbSuccess" ] = true />
    <cfset response[ "dbErrorMessage" ] = "" />

Handling Errors on the Server

Wrap ColdFusion’s try/catch around database transactions to capture errors. If there are errors, capture the error and insert each error into our ColdFusion response structure. This needs to be done for each error that was encountered. You can have multiple dbErrorMessage strings in each response. We are also changing the dbSuccess flag to false inside of the structure.


<cftry>  
    <cftransaction>            
        <!--- Update the DbSprocResult in the database --->
        <cfquery name="updateDbSprocResult" datasource="#dsn#">
            UPDATE dbo.DbSprocResult
            SET Success = <cfqueryparam value="1" cfsqltype="cf_sql_bit">,
            DateCompleted = getDate()
            WHERE DbSprocResultId = <cfqueryparam value="#DbSprocResultId#" cfsqltype="cf_sql_integer">
        </cfquery>
            
        <cfcatch type="database">
        
            <cfset sprocSuccess = false>
            
            <!--- Set the error message that we will send back to the client. --->
            <cfset errorMessage = cfcatch.Message & ' ' & replaceNoCase(cfcatch.detail, '[Macromedia][SQLServer JDBC Driver][SQLServer]', '')>
            <cfset errorMessage = errorMessage & ' The error was found on line ' & cfcatch.tagcontext[1].line & '.'>
            
            <!--- Set the response object. --->
            <cfset response[ "dbSuccess" ] = false />
            <cfset response[ "dbErrorMessage" ] = errorMessage />
            
        </cfcatch>
    </cftransaction>
</cftry>


Prepare and Serialize the Response Object on the Server

Once all of the database operations are complete, we need to serialize our ColdFusion structure to JSON using ColdFusion’s serializeJson method. It is necessary to convert the ColdFusion structure into JSON in order for JavaScript to understand the server data.


<!--- Prepare the response object. --->
    <cfset response[ "sprocName" ] = sprocName />
    <!--- Database error response objects are already prepared. --->
     
    <!--- Serialize the response --->
    <cfset serializedResponse = serializeJSON( response ) />
    
    <!--- Send the response back to the client. This is a custom function in the jsonArray.cfc template. --->
    <cfreturn serializedResponse>
</cffunction>

checkProcess JavaScript Method on the Client

The checkProcess callback method on the client is used to inspect the response object that was prepared on the server. Here, we are extracting the dbSuccess and dbErrorMessage strings within the JSON object and displaying the error message in a Kendo UI Dialog if there are any errors.  All errors will be shown if there is more than one error. There can be more than one dbErrorMessage strings sent back to the client.


function checkProcess(response, sprocName, processId){

    // Extract the data in the response.
    var sprocName = response.sprocName;
    var dbSprocResultId = response.dbSprocResultId;
    var dbSuccess = response.dbSuccess;
    var dbErrorMessage = response.dbErrorMessage;

    // Catch database errors
    if (dbErrorMessage.length){
        // Raise the alert message.
        $.when(kendo.ui.ExtAlertDialog.show({ title: "Error while consuming " + sprocName + ".", message: dbErrorMessage, icon: "k-ext-warning", width: "425px" }) // or k-ext-error, k-ext-question. You can also specify height.
            ).done(function () {
            // Do nothing
        });
    } else {//..if (data.length){
    
        // Do something else 
        
    }//..if (data.length){
}//..function checkProcess