Copy link to clipboard
Copied
In CF2021, an expression of the form
somevar[1].x
throws an exception when the value of x is null. This happens even when trying to test for null like IsNull(somevar[1].x)
There's no similar problem with somevar[1][1] or somevar.x.x or somevar.x[1] or even somevar[1][1].x.x[1].x[1].x.x.x as long as the variable and its contents have the appropriate types, and no problem with somevar[1].x when the x in the struct in the array is not null.
I tried many variations and the exception is thrown only in these specific circumstances: the next-to-last operation is an array element lookup, the last operation is a struct member lookup, and the value found in the struct is null.
If the array access and struct access are separated from each other by the use of a temporary variable, the exception doesn't happen.
The exception message is "Element X is undefined in a CFML structure referenced as part of an expression."
Here's a demo of the exception-throwing case, along with all the similar non-exception-throwing ones.
<cfscript>
/* Part 1: Array containing an array containing a null */
test_aan = [ [ null ] ]; /* set it */
v = test_aan[1][1]; /* get it */
WriteDump({test: "aan", v: v, v_is_null: IsNull(v)}); /* show it */
/* Part 2: Struct containing a struct containing a null */
test_ssn = { x: { x: null } }; /* set it */
v = test_ssn.x.x; /* get it */
WriteDump({test: "ssn", v: v, v_is_null: IsNull(v)}); /* show it */
/* Part 3: Struct containing an array containing a null */
test_san = { x: [ null ] }; /* set it */
v = test_san.x[1]; /* get it */
WriteDump({test: "san", v: v, v_is_null: IsNull(v)}); /* show it */
/* Part 4: Array containing a struct containing a number */
test_asi = [ { x: 1 } ]; /* set it */
v = test_asi[1].x; /* get it */
WriteDump({test: "asi", v: v, v_is_null: IsNull(v)}); /* show it */
/* Part 5: Array containing a struct containing a null */
test_asn = [ { x: null } ]; /* set it */
tmp = test_asn[1]; /* use tmp */
v = tmp.x; /* get it */
WriteDump({test: "asntmp", v: v, v_is_null: IsNull(v)}); /* show it */
/* Part 6: Array containing a struct containing a null
(try without a tmp variable - throws exception) */
test_asn = [ { x: null } ]; /* set it */
v = test_asn[1].x; /* get it */
WriteDump({test: "asn", v: v, v_is_null: IsNull(v)}); /* show it */
</cfscript>
Copy link to clipboard
Copied
You are right. There is inconsistency: Part 5 works, and Part 6 gives an error. Whereas we would expect them to have the same result.
If I were you I would report a bug.
Copy link to clipboard
Copied
This is now CF-4212947
(I am the original poster. My display name changed because accounts got merged when I logged into the bug tracker.)
Copy link to clipboard
Copied
Thanks for posting and for sharing the link.
I have voted to get the bug fixed.