ColdFusion中的cfcatch类型

Beg*_*ner 6 coldfusion struct try-catch

我只是使用一个cftry/cfcatch块来处理任何异常.拿这个简单的例外:

<cftry>
  <cfset abc = 1/0>
  <cfcatch>
    <cfdump var="#cfcatch.getClass().getName()#">
    <cfdump var="#isStruct(cfcatch)#">
    <cfdump var="#isObject(cfcatch)#">
    <cfdump var="#structKeyExists(cfcatch, 'type')#">
  </cfcatch>
</cftry>
Run Code Online (Sandbox Code Playgroud)

以上代码的输出如下:

coldfusion.runtime.DivideByZeroException 
NO 
YES 
YES
Run Code Online (Sandbox Code Playgroud)

我的问题是:

为什么structKeyExists不抛出cfcatch不是类型的错误struct

倾销cfcatch它似乎是一个struct.

有什么建议.

Mig*_*l-F 8

我觉得令你困惑的是你需要记住ColdFusion是一种无类型语言.

有关数据类型的ColdFusion文档

数据类型
ColdFusion通常被称为无类型,因为您没有为变量分配类型,ColdFusion不会将类型与变量名称相关联.但是,变量表示的数据确实具有类型,数据类型会影响ColdFusion如何计算表达式或函数参数.ColdFusion在评估表达式时可以自动将许多数据类型转换为其他数据类型.对于简单数据(如数字和字符串),在将变量用于表达式或函数参数之前,数据类型并不重要.
ColdFusion变量数据属于以下类型之一:

  • 简单的一个价值.可以直接在ColdFusion表达式中使用.包括数字,字符串,布尔值和日期时间值.
  • 二进制原始数据,例如GIF文件或可执行程序文件的内容.
  • 复杂**数据容器.通常代表多个值.ColdFusion内置的复杂数据类型包括数组,结构,查询和XML文档对象.您不能直接在ColdFusion表达式中使用复杂变量(如数组),但可以在表达式中使用复杂变量的简单数据类型元素.例如,使用名为myArray的一维数字数组,您不能使用表达式myArray*5.但是,您可以使用表达式myArray3*5将数组中的第三个元素乘以5.
  • 对象复杂的构造.通常封装数据和功能操作.下表列出了ColdFusion可以使用的对象类型,并标识了描述如何使用它们的章节:

所以<cfcatch>块中的代码包含一个可以称为"结构"的对象.默认情况下,该结构的名称是cfcatch.您可以通过name<cfcatch>标记中指定属性来覆盖该名称.

查看可用的所有内容的最简单方法是块<cfdump>内的整个结构<cfcatch>.

<cfcatch>
    <cfdump var="#cfcatch#">
</cfcatch>
Run Code Online (Sandbox Code Playgroud)

有关cfcatch的CFCatch文档

The cfcatch variables provide the following exception information:
cfcatch variable        Content
cfcatch.type            Type: Exception type, as specified in cfcatch.
cfcatch.message         Message: Exceptions diagnostic message, if provided; otherwise, an empty string; in the cfcatch.message variable.
cfcatch.detail          Detailed message from the CFML interpreter or specified in a cfthrow tag. When the exception is generated by ColdFusion (and not cfthrow), the message can contain HTML formatting and can help determine which tag threw the exception.
cfcatch.tagcontext      An array of tag context structures, each representing one level of the active tag context at the time of the exception.
cfcatch.NativeErrorCode Applies to type = "database". Native error code associated with exception. Database drivers typically provide error codes to diagnose failing database operations. Default value is -1.
cfcatch.SQLState        Applies to type = "database". SQLState associated with exception. Database drivers typically provide error codes to help diagnose failing database operations. Default value is 1.
cfcatch.Sql             Applies to type = "database". The SQL statement sent to the data source.
cfcatch.queryError      Applies to type ="database". The error message as reported by the database driver.
cfcatch.where           Applies to type= "database". If the query uses the cfqueryparam tag, query parameter name-value pairs.
cfcatch.ErrNumber       Applies to type = "expression". Internal expression error > number.
cfcatch.MissingFileName Applies to type = "missingInclude". Name of file that could not be included.
cfcatch.LockName        Applies to type = "lock". Name of affected lock (if the lock is unnamed, the value is "anonymous").
cfcatch.LockOperation   Applies to type = "lock". Operation that failed (Timeout, Create Mutex, or Unknown).
cfcatch.ErrorCode       Applies to type = "custom". String error code.
cfcatch.ExtendedInfo    Applies to type = "application" and "custom". Custom error message; information that the default exception handler does not display.
Run Code Online (Sandbox Code Playgroud)


Lei*_*igh 8

(评论太长了......)

添加到Miguel-F关于CF"无类型"的评论......根据文档,IsStruct使用以下规则(强调我的):

如果变量是ColdFusion结构或者是实现java.lang.Map接口的Java对象,则返回True .如果变量中的对象是用户定义的函数(UDF),则返回值为False.

CFCatch不符合该标准.因此为什么IsStruct返回false.

如果转储cfcatch对象并检查类层次结构,您将看到它实际上是作为java.lang.Exception的子类实现的:

coldfusion.runtime.DivideByZeroException
coldfusion.runtime.ExpressionException
coldfusion.runtime.NeoException
java.lang.RuntimeException
java.lang.Exception
java.lang.Throwable
java.lang.Object 
Run Code Online (Sandbox Code Playgroud)

......不是coldfusion.runtime.structCF结构:

coldfusion.runtime.Struct
coldfusion.util.FastHashtable
coldfusion.util.CaseInsensitiveMap
java.lang.Object 
Run Code Online (Sandbox Code Playgroud)

因此,作为米格尔-F说,虽然它可以用于一个结构(可最复杂的对象),在技术上这是不是一个CF结构,这可以解释为什么IsStruct返回false.

另外,您可以使用点表示法访问其属性的原因(如CF结构)可能是因为cfcatch类使用JavaBean模式:

如果Java类符合JavaBeans模式,ColdFusion可以自动调用get_PropertyName_()和set_PropertyName_(value)方法.因此,您可以通过直接引用它来设置或获取属性,而无需显式调用方法.

例如,您可以使用以下命令访问cfcatch的"message"属性:

     cfcatch.message
Run Code Online (Sandbox Code Playgroud)

..而不是为该属性调用其"getter"方法:

     cfcatch.getMessage()
Run Code Online (Sandbox Code Playgroud)


Tus*_*are 1

cfcatch 对象的行为就像一个结构体,但它不是一个结构体。这是一个特殊情况。

您可以做的是复制 cfcatch 对象并尝试对其使用 isStruct 方法,它将返回 true。

例如-

<cftry>
   <cfset abc = 1/0>
     <cfcatch>
       <cfset dup = duplicate(cfcatch)>           
       <cfdump var="#isStruct(dup)#">
       <cfdump var="#isStruct(cfcatch)#">
       <cfdump var="#isObject(cfcatch)#">
     </cfcatch>
</cftry>
Run Code Online (Sandbox Code Playgroud)

输出会像

YES
NO
YES
Run Code Online (Sandbox Code Playgroud)