我只是使用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>
以上代码的输出如下:
coldfusion.runtime.DivideByZeroException
NO
YES
YES
我的问题是:
为什么structKeyExists
没有抛出错误,因为cfcatch
不属于struct
类型?
在转储cfcatch
时,它似乎是struct
。
任何建议。
答案 0 :(得分:8)
我认为让您感到困惑的是,您需要记住ColdFusion是一种无类型的语言。
ColdFusion documentation on data types
数据类型
ColdFusion通常被称为无类型,因为您没有为变量分配类型,ColdFusion不会将类型与变量名称相关联。但是,变量表示的数据确实具有类型,数据类型会影响ColdFusion如何计算表达式或函数参数。 ColdFusion在评估表达式时可以自动将许多数据类型转换为其他数据类型。对于简单数据(如数字和字符串),在表达式或函数参数中使用变量之前,数据类型并不重要。
ColdFusion变量数据属于以下类型类别之一:
- 简单一个值。可以直接在ColdFusion表达式中使用。包括数字,字符串,布尔值和日期时间值。
- 二进制原始数据,例如GIF文件或可执行程序文件的内容。
- 复杂**数据容器。通常代表多个值。 ColdFusion内置的复杂数据类型包括数组,结构,查询和XML文档对象。您不能直接在ColdFusion表达式中使用复杂变量(如数组),但可以在表达式中使用复杂变量的简单数据类型元素。例如,使用名为myArray的一维数字数组,您不能使用表达式myArray * 5.但是,您可以使用表达式myArray3 * 5将数组中的第三个元素乘以5。
- 对象复杂的构造。通常封装数据和功能操作。下表列出了ColdFusion可以使用的对象类型,并列出了描述如何使用它们的章节:
因此<cfcatch>
块中的代码包含一个可被称为&#34;结构的对象&#34;。默认情况下,该结构的名称为cfcatch
。您可以通过在name
代码中指定<cfcatch>
属性来覆盖该名称。
查看所有可用内容的最简单方法是<cfdump>
<cfcatch>
块中的整个结构。
<cfcatch>
<cfdump var="#cfcatch#">
</cfcatch>
CFCatch documentation on 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.
答案 1 :(得分:8)
(评论太长了......)
添加Miguel-F关于CF&#34;无类型的评论&#34; ...根据文档,IsStruct使用以下规则(强调我的):< / p>
如果变量是ColdFusion结构或是Java,则返回True 实现java.lang.Map接口的对象。返回值 如果变量中的对象是用户定义的函数(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
...不是coldfusion.runtime.struct
即CF结构:
coldfusion.runtime.Struct
coldfusion.util.FastHashtable
coldfusion.util.CaseInsensitiveMap
java.lang.Object
所以as Miguel-F said,虽然它可以像一样使用结构(就像最复杂的对象一样),但从技术上来说它是而不是 CF结构,这解释了为什么IsStruct返回false。
顺便说一下,你可以使用点表示法访问其属性的原因,例如CF结构,可能是因为cfcatch类使用the JavaBean pattern:
ColdFusion可以自动调用get_PropertyName_()和 set_PropertyName_(value)方法,如果Java类符合 JavaBeans模式。因此,您可以设置或获取属性 直接引用它,而不必显式调用方法。
例如,您可以访问&#34;消息&#34; cfcatch的财产使用:
cfcatch.message
..而不是调用它的&#34; getter&#34;该属性的方法:
cfcatch.getMessage()
答案 2 :(得分: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>
输出就像
YES
NO
YES