ColdFusion中的cfcatch类型

时间:2015-06-03 11:15:35

标签: struct coldfusion 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>

以上代码的输出如下:

coldfusion.runtime.DivideByZeroException 
NO 
YES 
YES

我的问题是:

为什么structKeyExists没有抛出错误,因为cfcatch不属于struct类型?

在转储cfcatch时,它似乎是struct

任何建议。

3 个答案:

答案 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