[frs-372] Use FRAPI To Log CFThrow Errors, and Set HTTP Response Codes

Problem

You've got a CF error handling template which you use to log or respond to cfthrow exceptions. You can integrate this with FusionReactor to:

  • Have the error recorded and reported on FusionReactor's Error Details tab.
  • Record the details of the error as FR traces, which appear on the Traces tab.
  • Change the response code to 500.

Procedure

The following code can be used to achieve this.

This code is also available at as a gist.

<cftry>
    <!-- Some code that would ordinarily raise some exception -->

    <cfthrow type = "MyApplicationError"
             message = "Custom MyApplicationError Exception"
             detail = "Something untoward occurred in this CF page!"
             errorCode = "500" />

    <cfcatch type = "MyApplicationError">
        
        <!-- The following code locates this thread's current master transaction 
             and sets it in error.  It is presented in cfscript, but would be a good 
             candidate to become a function on a CFC, for instance. -->

        <cfscript>
        
            // Get some useful objects to talk to FR
            frapiClass = createObject("java","com.intergral.fusionreactor.api.FRAPI");
            Thread = createObject("java", "java.lang.Thread");
            Throwable = createObject("java", "java.lang.Throwable");
            frapi = frapiClass.getInstance();
            requests = frapi.getRunningRequests();

            // Find the FR Request object that's running this request

            for( i = 1; i LTE ArrayLen(requests); i++ )
            {
                frRequest = requests[i];
                if( frRequest.getThread() == Thread.currentThread().getName() )
                {
                    // Now we've found 'ourselves', get the FRAPI Transit 
                    // master transaction (how FR tracks things internally)
                    txnField = frRequest.getClass().getDeclaredField( "txn" );
                    txnField.setAccessible( true );
                    txn = txnField.get( frRequest );

                    if( isNull( txn.getMasterTransaction() ) )
                        masterTxn = txn;
                    else
                        masterTxn = txn.getMasterTransaction();

                    // We now set the error on the master transaction.
                    // This ensures the error appears in the 'Error Details'
                    // tab of the FR request.
                    appError = Throwable.init( cfcatch.message );
                    appError.fillInStackTrace();
                    masterTxn.setTrappedThrowable( appError ); 

                    // Record the original cfcatch as a trace message for
                    // full details
                    frapi.trace( cfcatch.type );
                    frapi.trace( cfcatch.message );
                    frapi.trace( cfcatch.detail );

                    // Set the page result to 500
                    getPageContext().getResponse().setStatus( cfcatch.errorCode );
                }
            }

        </cfscript>
    </cfcatch>
</cftry>

Issue Details

Type: Technote
Issue Number: FRS-372
Components: FRAPI
Environment:
Resolution: Fixed
Last Updated: 12/Nov/15 12:22 PM
Affects Version: 4.5.0, 5.0.0, 5.2.8
Fixed Version: 6.x
Server:
Platform:
Related Issues:

FRS-366: Workaround: 0 Query Count Returned From FRAPI Request Objects

Comments are closed.