Type cfcatch in ColdFusion

I just use the cftry/cfcatch to handle any exception. Take this simple exception:

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

And the above code output looks like this:

 coldfusion.runtime.DivideByZeroException NO YES YES 

My question is:

Why structKeyExists n't structKeyExists throw an error since cfcatch not of type struct ?

And when dumping cfcatch it seems to be a struct .

Any suggestions.

+6
source share
3 answers

I think it bothers you that you need to remember that ColdFusion is an unprincipled language.

ColdFusion Data Type Documentation

Data types
ColdFusion is often called causeless because you do not assign types to variables, and ColdFusion does not bind a type to a variable name. However, the data that the variable represents is of type, and the data type affects how ColdFusion evaluates the expression or argument of the function. ColdFusion can automatically convert many data types to others when evaluating expressions. For simple data, such as numbers and strings, the data type is not important until the variable is used in an expression or as an argument to a function.
ColdFusion variable data belongs to one of the following type categories:

  • Simple one value. Can be used directly in ColdFusion expressions. Include numbers, strings, booleans, and date and time values.
  • Binary source data, such as the contents of a GIF file or program executable file.
  • Complex ** Data container. Usually represent several values. ColdFusion's built-in complex data types include arrays, structures, queries, and XML document objects. You cannot use a complex variable, such as an array, directly in a ColdFusion expression, but you can use simple data type elements of a complex variable in an expression. For example, with a one-dimensional array of numbers myArray, you cannot use the expression myArray * 5. However, you can use the expression myArray3 * 5 to multiply the third element in the array by five.
  • Objects Complex constructions. Often encapsulate both data and functional operations. The following table lists the types of objects that ColdFusion can use and identifies chapters that describe how to use them:

Thus, the code in the <cfcatch> block contains an object that can be called a "structure". The default name for this structure is cfcatch . You can override this name by specifying the name attribute in the <cfcatch> .

The easiest way to see everything that is available to you is the <cfdump> whole structure in the <cfcatch> block.

 <cfcatch> <cfdump var="#cfcatch#"> </cfcatch> 

CFCatch cfcatch documentation

 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. 
+8
source

(Too long for comments ..)

Adding to Miguel-F comments on CF "unscrupulousness" ... according to the documentation, IsStruct uses the following rules (my attention):

Returns True if the variable is a ColdFusion structure or is a Java object that implements the java.lang.Map interface . Return value False if the object in the variable is a user-defined function (UDF).

CFCatch does not meet these criteria. Therefore, why IsStruct returns false.

If you CFCatch object and examine the class hierarchy, you will see that it is actually implemented as a subclass of java.lang.Exception :

 coldfusion.runtime.DivideByZeroException coldfusion.runtime.ExpressionException coldfusion.runtime.NeoException java.lang.RuntimeException java.lang.Exception java.lang.Throwable java.lang.Object 

... not coldfusion.runtime.struct i.e. CF structure:

 coldfusion.runtime.Struct coldfusion.util.FastHashtable coldfusion.util.CaseInsensitiveMap java.lang.Object 

So, as Miguel-F said , although it can be used as a structure (like the most complex object), it is technically not a CF structure, which explains why IsStruct returns false.

Aside, the reason you can access your properties using dot notation, for example with CF structures, is probably because the cfcatch class uses the JavaBean pattern :

ColdFusion can automatically call get_PropertyName_ () and set_PropertyName_ (value) if the Java class matches the JavaBeans pattern. As a result, you can set or get referring to it directly, without explicitly calling the method.

So, for example, you can access the "message" cfcatch property using:

  cfcatch.message 

.. instead of calling its getter method for this property:

  cfcatch.getMessage() 
+8
source

The cfcatch object acts as a structure, but it is not alone. This is a special case.

What you can do is duplicate the cfcatch object and try the isStruct method on it, it will return true.

eg -

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

The output will look like

 YES NO YES 
+1
source

Source: https://habr.com/ru/post/988442/


All Articles