
Lieven De Foor (TVH Parts Holding) asked a question.
Safe navigation operator (?:) not working when chained using .NET properties?
- /*------------------------------------------------------------------------
- File : repro_safe_nav.p
- Description : Standalone reproducible case demonstrating
- unhandled 10068 error when chaining ?: on .NET properties.
- ----------------------------------------------------------------------*/
- block-level on error undo, throw.
-
- using System.Xml.XmlDocument from assembly.
-
- define variable oDoc as XmlDocument no-undo.
- define variable cDocName as character no-undo.
-
- /* Initialize an empty XmlDocument */
- oDoc = new XmlDocument().
-
- /*
- Case 1: Standard Chained Safe-Navigation on .NET Properties (FAILS)
- Since oDoc is empty, oDoc:DocumentElement evaluates to null (?).
- */
- do on error undo, throw:
- message "Running Case 1: Chained ?. operator..." view-as alert-box.
- cDocName = oDoc:DocumentElement?:Name.
- message "Case 1 Success! Document Name: " string(cDocName) view-as alert-box.
-
- catch e as Progress.Lang.Error:
- message "Case 1 Failed! Error: " e:GetMessage(1) view-as alert-box.
- end catch.
- end.
-
- /*
- Case 2: Safe-Navigation using a Local Variable (SUCCEEDS)
- */
- do on error undo, throw:
- message "Running Case 2: Local variable assignment first..." view-as alert-box.
- define variable oElem as System.Xml.XmlElement no-undo.
- oElem = oDoc:DocumentElement.
- cDocName = oElem?:Name.
- message "Case 2 Success! Document Name: " string(cDocName) view-as alert-box.
-
- catch e as Progress.Lang.Error:
- message "Case 2 Failed! Error: " e:GetMessage(1) view-as alert-box.
- end catch.
- end.
Case 1 fails, case 2 succeeds...
Is this expected?
Doing the same with pure ABL Objects works as expected:
- class ReproChild:
- define public property Name as character no-undo get. set.
- end class.
-
- class ReproParent:
- define public property Child as ReproChild no-undo get. set.
- end class.
-
- /*
- Case 3: Standard Chained Safe-Navigation on Pure ABL Objects (SUCCEEDS)
- Since oParent:Child is UNKNOWN (?).
- */
- do on error undo, throw:
- message "Running Case 3: Chained ?. operator on Pure ABL Objects..." view-as alert-box.
- define variable oParent as ReproParent no-undo.
- define variable cChildName as character no-undo.
-
- oParent = new ReproParent().
- cChildName = oParent:Child?:Name.
- message "Case 3 Success! Child Name: " string(cChildName) view-as alert-box.
-
- catch e as Progress.Lang.Error:
- message "Case 3 Failed! Error: " e:GetMessage(1) view-as alert-box.
- end catch.
- end.
The documentation does not mention this is limited to pure ABL objects (i.e. no .NET or hybrids)
Seems to fail the same way using 12.8.9 and 13.0.
I'm inclined to call this a defect.
If this was expected to fail, I'd expect to see "The safe navigation operator cannot be used with static, enum, SUPER or handle-based references. (20395)" at compile-time.
Instead, we get the classic runtime "Lead attributes in a chained-attribute expression (a:b:c) must be type HANDLE or a user-defined type and valid (not UNKNOWN). (10068)". Where the whole idea behind safe navigation is to suppress that error, and resolve the chain to Unknown instead. If the code path involved can throw the error, it should also be able to suppress it.
I've created a support case.
OCTA-94245