tracker issue : CF-4190050

select a category, or use search below
(searches all categories and all time range)
Title:

Exceptions in REST services do not pass exception information to Application.cfc onError() handler

| View in Tracker

Status/Resolution/Reason: Closed/Withdrawn/UserError

Reporter/Name(from Bugbase): Mosh Teitelbaum / Mosh Teitelbaum (Mosh Teitelbaum)

Created: 09/16/2016

Components: REST Services

Versions: 2016

Failure Type:

Found In Build/Fixed In Build: CF2016_Update2 /

Priority/Frequency: Major / All users will encounter

Locale/System: English / Windows 10 64 bit

Vote Count: 1

Problem Description:
Exceptions thrown in REST services are caught by the Application.cfc file's onError() handler but the handler's "Exception" argument is mostly empty instead of being populated with the details of the exception.  Exception.TagContext includes context information but Type, Message, Detail, ErrorCode, and ExtendedInfo are all empty.

Steps to Reproduce:
error.cfc
------------
<cfcomponent rest="true" restpath="/error" produces="application/json,text/xml">
	<cffunction name="doError" access="remote" returnType="void" httpMethod="GET">
		<cfthrow type="RestError" errorcode="503" message="message" detail="detail" extendedinfo="extendedInfo" />
	</cffunction>
</cfcomponent>

Application.cfc
---------------------
<cffunction name="onError" output="false" returnType="void">
	<cfargument name="Exception" required="true" />
	<cfargument name="EventName" required="true" />

	<cfset content = {} />
	<cfset content["eventName"] = arguments.EventName />
	<cfset content["type"] = arguments.Exception.type />
	<cfset content["message"] = arguments.Exception.message />
	<cfset content["detail"] = arguments.Exception.detail />
	<cfset content["tagContext"] = arguments.Exception.tagContext />
	<cfset content["errorCode"] = arguments.Exception.errorCode />
	<cfset content["extendedInfo"] = arguments.Exception.extendedInfo />

	<cfset resp.status = 500 />
	<cfset resp.content = SerializeJSON(content) />
	<cfset restSetResponse(resp) />
</cffunction>


Actual Result:
cfhttp.FileContent.detail = ""
cfhttp.FileContent.errorCode = ""
cfhttp.FileContent.eventName = ""
cfhttp.FileContent.extendedInfo = ""
cfhttp.FileContent.message = ""
cfhttp.FileContent.tagContext = <tag context referring to cfthrow>
cfhttp.FileContent.type = "java.lang.reflect.InvocationTargetException"

Expected Result:
cfhttp.FileContent.detail = "detail"
cfhttp.FileContent.errorCode = "503"
cfhttp.FileContent.eventName = <unsure>
cfhttp.FileContent.extendedInfo = "extendedInfo"
cfhttp.FileContent.message = "message"
cfhttp.FileContent.tagContext = <tag context referring to cfthrow>
cfhttp.FileContent.type = "RestError"

Any Workarounds:
The onError() handler can access scoped variables that are also accessible in the REST services.  Each REST service can wrap everything in a cftry/cfcatch block and, when an exception is caught, save the cfcatch details to a shared scope (e.g., request) and then rethrow an exception to be caught by the onError handler.  However, this requires adding that additional code in every method that might throw an exception.

----------------------------- Additional Watson Details -----------------------------

Watson Bug ID:	4190050

External Customer Info:
External Company:  
External Customer Name: Moshe Teitelbaum
External Customer Email:  
External Test Config: My Hardware and Environment details:

Win10 64-bit laptop.

CF2016 Enterprise (Update 2)

Attachments:

Comments:

bug reproduced in CF11
Vote by Henry H.
1801 | April 05, 2017 10:22:33 PM GMT
Dumping the arguments.Exception to file, I can see the actual exception is actually being wrapped, resided in Exception.cause.cause
Comment by Henry H.
1800 | April 05, 2017 10:45:56 PM GMT