您提供的符号不是功能

Dan*_*ort 2 coldfusion coldfusion-8


进一步阅读之前的要点

  1. 所有变量都适当变化(你必须相信我)
  2. 在这些长时间运行的进程发生时,范围不会被重置
  3. 当转储所谓的缺失/无效方法的元数据时,我得到了正确的信息
  4. 应用程序中只引用了此方法名称的两个位置.一旦它被定义,一旦在下面的代码中调用该方法.

我有一个非常奇怪的间歇性错误,我似乎无法追查.这是背景(这些都被严格修剪以简化发布).

FeedService.cfc:

<cfcomponent output="false" extends="FeedDAO">

    <cffunction name="processXmlFile" access="public" output="false" returntype="struct">
        <cfset Var local = StructNew() />

/***************************************
THE VARIABLES ARE ALL VAR'D - PROMISE!!!
Lots of other stuff goes on in here to get the ultimate set of XML nodes to loop through
*****************************************/

        <cfloop from="1" to="#ArrayLen(local.arrChannels)#" index="local.currentChannelItem">
            ... Lots of XML parsing and stuff and things going on here ...

            <cfset LOCAL.invCheck = checkCustomerListing(
                Acct_ID = local.invStruct.AcctID
                , CustomerListingID = local.invStruct.CustomerListingID
            ) />

            ... Lots more stuff going on here ...

        </cfloop>
    </cffunction>
</cfcomponent>
Run Code Online (Sandbox Code Playgroud)

FeedDAO:

<cfcomponent output="false">

    <cffunction name="checkCustomerListing" access="public" output="false" returntype="numeric" hint="Returns the numeric inventory ID for an existing inventory listing, or 0 if the listing doesn't exist.">
        <cfargument name="Acct_ID" type="numeric" required="true" hint="" />
        <cfargument name="CustomerListingID" type="string" required="true" hint="" />
        <cfset var rs = "">

        <cfquery name="rs" datasource="#Variables.DSNs.Primary#">
            SELECT ID FROM TheTable
            WHERE
                Acct_ID = <cfqueryparam cfsqltype="cf_sql_integer" value="#Arguments.Acct_ID#" />
                AND Customer_Listing_ID = <cfqueryparam cfsqltype="cf_sql_varchar" value="#Arguments.CustomerListingID#" />
        </cfquery>

        <cfif rs.RecordCount>
            <cfreturn rs.Inv_ID />
        <cfelse>
            <cfreturn 0 />
        </cfif>

    </cffunction>

</cfcomponent>  
Run Code Online (Sandbox Code Playgroud)

我正在调用这样的初始函数:

<cfset processStruct = Server.FeedService.processXmlFile(filePath) />
Run Code Online (Sandbox Code Playgroud)

因此,当Feed被提交到processXMLFile函数时,它会查看文件中的所有项目.Feed文件可能包含10个,100个甚至1000个条目.在处理文件时偶尔会收到类似的错误消息:

[struct]
Detail: The symbol you provided checkCustomerListing is not the name of a function.
Message: Entity has incorrect type for being called as a function.
StackTrace: coldfusion.runtime.CfJspPage$UninvocableEntityException: Entity has incorrect type for being called as a function.
    at coldfusion.runtime.CfJspPage._invokeUDF(CfJspPage.java:2441)
    at coldfusion.runtime.SuperScope.invoke(SuperScope.java:18)
    at coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2222)
Run Code Online (Sandbox Code Playgroud)

更多堆栈转储信息

    Type: Application
    symbolName: checkCustomerListing

    [object of coldfusion.runtime.CfJspPage$UninvocableEntityException]
    Class Name: coldfusion.runtime.CfJspPage$UninvocableEntityException
    Fields: 
        java.lang.String symbolName: checkCustomerListing
    Parent Class: [object of coldfusion.runtime.ApplicationException]
        Class Name: coldfusion.runtime.ApplicationException
        Parent Class: [object of coldfusion.runtime.NeoException]
            Class Name: coldfusion.runtime.NeoException
            Methods:  
                findAdvancedCFTarget(coldfusion.runtime.AdvancedCFException, java.lang.String[]) returns int 
                findCustomTarget(coldfusion.runtime.CustomException, java.lang.String[]) returns int 
                findThrowableTarget(java.lang.Throwable, java.lang.String[]) returns int 
                getDetail() returns java.lang.String 
                getLocalizedMessage() returns java.lang.String 
                getMessage() returns java.lang.String 
                getRootCause() returns java.lang.Throwable 
                getString(java.lang.Throwable, java.lang.String, java.util.Locale) returns java.lang.String 
                getType() returns java.lang.String 
                setLocale(java.util.Locale) returns void 
                unwrap(java.lang.Throwable) returns java.lang.Throwable
            Parent Class: [object of java.lang.RuntimeException]
                Class Name: java.lang.RuntimeException
                Parent Class: [object of java.lang.Exception]
                    Class Name: java.lang.Exception
                    Parent Class: [object of java.lang.Throwable]
                        Class Name: java.lang.Throwable
                        Methods:  
                            fillInStackTrace() returns java.lang.Throwable 
                            getCause() returns java.lang.Throwable 
                            getLocalizedMessage() returns java.lang.String 
                            getMessage() returns java.lang.String 
                            getStackTrace() returns java.lang.StackTraceElement[] 
                            initCause(java.lang.Throwable) returns java.lang.Throwable 
                            printStackTrace(java.io.PrintWriter) returns void 
                            printStackTrace(java.io.PrintStream) returns void 
                            printStackTrace() returns void 
                            setStackTrace(java.lang.StackTraceElement[]) returns void 
                            toString() returns java.lang.String
Run Code Online (Sandbox Code Playgroud)

我可能会在1000个条目中收到一个错误,或者我可能会同时收到一小批错误,其余的Feed进程也很好(由于一些try/catch逻辑可以防止整个事情被淘汰).有一次,它checkCustomerListing是一个完全不同的服务器范围对象,我从来没有遇到过问题.我将它移入FeedDAO并通过超级范围开始调用它,这就是这些间歇性错误开始的时候.

更新:我有一切正确的变化,我只是为了简洁而全部切碎.

再次更新:更改了代码示例注释,以明确在第一个循环开始之前有很多内容正在进行,包括设置将在循环中使用的所有LOCAL变量.

更多代码信息:我应该注意,我们的整个应用程序中只有两个位置(成千上万行代码),其中存在字符串'checkCustomerListing'.一个是调用函数的地方,两个是声明函数的地方.checkCustomerListing任何地方都没有其他字符串实例.

更新:2011年9月6日

我添加了一些额外的错误检查,看看我是否能找到应用程序的想法checkCustomerListing(感谢Adam和Ryan).这是我的新try/catch语句:

<cfcatch type="any">
    <cfset local.tmpError.cfcatch = cfcatch>

    <cfif isDefined("checkCustomerListing")>
        <cfset local.tmpError.customerListing = checkCustomerListing />
        <cfset local.tmpError.customerListingMeta = getMetaData(checkCustomerListing) />
    <cfelse>
        <cfset local.tmpError.customerListing = "Checkcustomerlisting is not defined" />
    </cfif>

    <cfset Server.Utilities.Errors.emailCaughtError(local.tmpError)>

</cfcatch>
Run Code Online (Sandbox Code Playgroud)

所以我今天早上收到错误,在收到的电子邮件customerListing中,转储中没有节点,但有一个元节点:

CUSTOMERLISTINGMETA:  
    [struct]
    ACCESS: public
    HINT: Returns the numeric inventory ID for an existing inventory listing, or 0 if the listing doesn't exist.
    NAME: checkCustomerListing
    OUTPUT: false
    PARAMETERS:  
        [array]
        1) [struct]
            HINT: [empty string]
            NAME: Acct_ID
            REQUIRED: true
            TYPE: numeric 
        2) [struct]
            HINT: [empty string]
            NAME: CustomerListingID
            REQUIRED: true
            TYPE: string 
    RETURNTYPE: numeric
Run Code Online (Sandbox Code Playgroud)

所有这些元信息都是完全正确的...所以如果它能找到函数的元数据,为什么它不能找到函数本身呢?

Ada*_*ron 7

这通常是由于缺乏VARing而导致的,正如其他人所暗示的那样.通常人们都有一个名为"getStuff"的私有函数,并且在其中有一个名为"getStuff"的查询.如果变量不是VARed,那么getStuff查询结果将进入CFC的变量范围,这将覆盖函数getStuff,因为它也位于变量范围内.

因此,请检查checkCustomerListing对任何非VARed(或在本地范围内)的同名变量的使用情况.

(并注意checkCustomerListing变量不需要在同一方法内发生......它可能在CFC中的任何地方或任何扩展或超级CFC ......)