When I use what you suggested in post 7. and call a function to test throwing the custom REST errors I get the error below.
| Element 803 is undefined in a CFML structure referenced as part of an expression. |
It seems like the variables.RESTErrorCodes is an empty struct. When I tried using what I had in post 6 it appears to work. Am I overlooking something?
You overlooked nothing, I overlooked some. When I looked closer I saw that the problem is a bit more complicated than I at first thought.
If we use init, then it has to be run before any other call to the CFC. Either by the caller or by the CFC itself.
Case 1) Init run by the CFC itself:
If you choose to let the CFC run the init itself, as you have done, then you indeed have to use both lines of code:
<cfset variables.RESTErrorCodes = structNew()>
<cfset init(RESTErrorCodes=application.RESTErrorCodes) />
However, this is not yet optimal, as it still couples the CFC to the application scope.
2) Letting the caller call init:
This is a preferable solution (in an object-oriented sense). But when I look back at your initial question I see a problem I had overlooked. Your CFCs are meant to be RESTful.
This implies calls to them will be stateless. We cannot then expect to carry the result of an init call (the this object) over to the next call. We should therefore think of a solution in which the caller passes an argument, for example, the application-name, to the RESTful CFC. And so we arrive at a possible solution, similar to WolfShade's.
Create a database table, errorCodes, and register it as datasource in the ColdFusion administrator. It will have data as in the following example:

Corresponding to this table will be the CFC errorcodes.cfc, containing the init.
errorcodes.cfc
<cfcomponent>
<cffunction name="init" access="remote" returntype="Struct">
<cfargument name="appName" type="string" default="myRestApp">
<cfset var RESTErrorCodes = structNew()>
<!--- For speed and efficiency: My current applicationtimeout value is 2 days, so I cache the query for 2 days --->
<cfquery name="getErrorCodes" datasource="myDsn" cachedwithin="#createTimespan(2,0,0,0)#">
select errorkey, errordetail, errormessage, errortype
from errorCodes
where applicationName = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.appName#">
order by errorKey
</cfquery>
<!--- Assemble the RESTErrorCodes struct --->
<cfoutput query="getErrorCodes">
<cfset RESTErrorCodes[getErrorCodes.errorkey[currentrow]]={detail=getErrorCodes.errordetail[currentrow],message=getErrorCodes.errormessage[currentrow],type=getErrorCodes.errortype[currentrow]}>
</cfoutput>
<cfreturn RESTErrorCodes>
</cffunction>
</cfcomponent>
All the caller has to do is pass the application's name along with the other arguments in the REST call. The REST CFCs will be something like
<cfcomponent rest="true" restpath="/etc">
<cffunction name="getSomething" access="remote" httpmethod="get" returntype="any" output="false">
<cfargument name="arg1" type="string" required="yes"/>
<cfargument name="arg2" type="numeric" required="yes"/>
<cfargument name="appName" type="string" required="no" />
<cfset var RESTErrorCodes = structNew()>
<!--- Get the error codes for a particular application --->
<cfset var errorCodeObj = createObject("component", "errorCodes")>
<cfset RESTErrorCodes = errorCodeObj.init(arguments.appName)>
<!--- Rest of business code goes here --->
<cfreturn something>
</cffunction>
</cfcomponent>