Pergunta

The Basics

I'm running a CF10u10 box with Apache as web server on my local machine. I'm fan of cfscript and like to use the new implicit struct {} declaration Vs structNew() whenever possible.

The Code

Files are one component and one CFM.

componentFile.cfc

<cfcomponent output="false">

    <cffunction name="blahExplicit" returntype="Struct">
        <cfset var name = 'ColdFusion'/>
        <cfset var ret = structNew()/>
        <cftry>
                <cfreturn {success: true, data: name}/>
            <cfcatch type="any">
                <cfset ret.success = false />
                <cfset ret.data = cfcatch />
                <cfreturn ret/>
            </cfcatch>
        </cftry>
    </cffunction>

    <cffunction name="blahImplicit" returntype="Struct">
        <cfset var name = 'ColdFusion'/>
        <cftry>
                <cfreturn {success: true, data: name}/>
            <cfcatch type="any">
                <cfreturn {success: false, data: cfcatch.detail}/>
            </cfcatch>
        </cftry>
    </cffunction>

    <cffunction name="script_blahExplicit" returntype="Struct">
        <cfscript>
            var name = 'ColdFusion';
            var ret = structNew();
            try{
                return {success: true, data: name};
            } catch(Any err){
                    ret.success = false;
                    ret.data = err.detail;
                    return ret;
            }
        </cfscript>
    </cffunction>

    <cffunction name="script_blahImplicit" returntype="Struct">
        <cfscript>
            var name = 'ColdFusion';
            try{
            return {success: true, data: name};
            } catch(Any err){
                return {success: false, data: err.detail};
            }
        </cfscript>
    </cffunction>
</cfcomponent>

cfcatchErr.cfm

<cfset cObj = createObject("component","componentFile")/>
<cfdump var="#cObj.blahExplicit()#" label="blah Explicit"/>
<cfdump var="#cObj.script_blahExplicit()#" label="blah Explicit With Script"/>
<cfdump var="#cObj.script_blahImplicit()#" label="blah Implicit With Script"/>
<cfdump var="#cObj.blahImplicit()#" label="blah Implicit"/>

The Problem

The parser throws an error stating detail is undefined in cfcatch for the blahImplicit() method. But it is all okay for the remaining methods

Where as the code in blahExplicit(),script_blahExplicit(),script_blahImplicit() just works fine.

The Question

Why is this happening? Why is CF throwing an error even without running the code? It is throwing the error at parse time itself. I used ACF Builder and found that the control jumps to catch as soon as it reaches try.

Is this a known issue or something new? Why is returning an implicit struct a problem?

ScreenShot Error with Implicit Struct

Stack Trace

coldfusion.runtime.UndefinedElementException: Element DETAIL is undefined in CFCATCH.
    at coldfusion.runtime.CfJspPage.resolveCanonicalName(CfJspPage.java:1752)
    at coldfusion.runtime.CfJspPage._resolve(CfJspPage.java:1705)
    at coldfusion.runtime.CfJspPage._resolveAndAutoscalarize(CfJspPage.java:1854)
    at coldfusion.runtime.CfJspPage._resolveAndAutoscalarize(CfJspPage.java:1833)
    at cfcomponentFile2ecfc947108420$funcBLAHIMPLICIT.runFunction(C:\ColdFusion10\cfusion\wwwroot\fresh\componentFile.cfc:21)
    at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:472)
    at coldfusion.runtime.UDFMethod$ReturnTypeFilter.invoke(UDFMethod.java:405)
    at coldfusion.runtime.UDFMethod$ArgumentCollectionFilter.invoke(UDFMethod.java:368)
    at coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:55)
    at coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:321)
    at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:220)
    at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:655)
    at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:444)
    at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:414)
    at coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2432)
    at cf62ecfm1194236173.runPage(C:\ColdFusion10\cfusion\wwwroot\fresh\cfcatchErr.cfm:5)
    at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:244)
    at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:444)
    at coldfusion.filter.CfincludeFilter.invoke(CfincludeFilter.java:65)
    at coldfusion.filter.IpFilter.invoke(IpFilter.java:64)
    at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:449)
    at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40)
    at coldfusion.filter.PathFilter.invoke(PathFilter.java:112)
    at coldfusion.filter.LicenseFilter.invoke(LicenseFilter.java:30)
    at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:94)
    at coldfusion.filter.BrowserDebugFilter.invoke(BrowserDebugFilter.java:79)
    at coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28)
    at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38)
    at coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:46)
    at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38)
    at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)
    at coldfusion.filter.CachingFilter.invoke(CachingFilter.java:62)
    at coldfusion.CfmServlet.service(CfmServlet.java:219)
    at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42)
    at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:928)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:414)
    at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:204)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:539)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:298)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:722)

Note: I like Railo too, but lets only talk about CF 10 in this case. I submitted a bug to Adobe.

Foi útil?

Solução

It definitely a bug in CF, so good that you logged it as such (3605215).

The most expedient work-around I could come up with is to use an intermediary variable, eg:

<cffunction name="blahImplicit" returntype="Struct">
    <cfset var name = 'ColdFusion'/>
    <cftry>
            <cfreturn {success= true, data= name}>
        <cfcatch type="any">
        <cfset var ret = {success= false, data= cfcatch.detail}><!--- this will prevent the error --->
            <cfreturn ret>
        </cfcatch>
    </cftry>
</cffunction>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top