cancel
Showing results for 
Search instead for 
Did you mean: 

Fatal Error when reading optional from proxy class

perage
Participant
0 Kudos

Hi,

I have disabled the generation of optionals for non-nullable attributes in my proxy classes, and now I get a fatal error when trying to access one of them.

            <EntityType Name="ProductGroup" sap:content-version="1">
                <Key>
                    <PropertyRef Name="Id"/>
                </Key>
                <Property Name="Id" Type="Edm.String" Nullable="false" MaxLength="18" sap:unicode="false" sap:label="Prod.hierarchy" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
                <Property Name="ImageUrl" Type="Edm.String" MaxLength="132" sap:unicode="false" sap:label="URL" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
                <Property Name="Title" Type="Edm.String" Nullable="false" MaxLength="60" sap:unicode="false" sap:label="Mat.Grp Desc. 2" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
                <Property Name="Parent" Type="Edm.String" MaxLength="18" sap:unicode="false" sap:label="Prod.hierarchy" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
            </EntityType><br>

In swift, when calling

return commonData.productGroups.filter { $0.parent?.isEmpty ?? true }<br>

I get the following fatal error

SAPOData/xscript_core.swift:4635: Fatal error: 'try!' expression unexpectedly raised an error: 
UndefinedException: Cannot get property 'Parent' of type 'string?' in entity type 'API_SRV.ProductGroup', 
because the value is not set. This exception occurs because an undefined property is considered distinct 
from a null property (regardless of whether or not the property is defined as nullable in the service metadata). 
The attempt to access an undefined property may be evidence of a flaw in this client application 
(trying to access properties in a query result without having requested for the server to return values for the properties, 
or trying to access property values before initializing them), or may be evidence of a flaw in the service implementation 
(failing to return properties that were requested by the client application using $select or $expand). 
Depending on the root cause, options to avoid this exception include: 
(1) Getting the service implementer to fix the service if it is unexpectedly omitting expected property values in responses; 
(2) Initializing all properties in newly created objects before trying to access the properties (using the 'setDefaultValues' function, 
or by specifying 'true' for the 'withDefaults' parameter of the proxy class initializer); 
(3) Using the 'hasDataValue' function to check if properties are defined before trying to access them; 
(4) With the dynamic API, using the 'getOptionalValue' function instead of using the 'getDataValue' function.<br>

One entity in a postman response

    {
                "__metadata": {
                    "id": "http://IP:8000/sap/opu/odata/z/api_srv/ProductGroupSet('10000002')",
                    "uri": "http://IP:8000/sap/opu/odata/z/api_srv/ProductGroupSet('10000002')",
                    "type": "API_SRV.ProductGroup"
                },
                "Id": "10000002",
                "ImageUrl": "",
                "Title": "Fruit – Unprepared/Unprocessed (Frozen)",
                "Parent": ""
            },<br>

Terminal script

sapcpsdk-proxygenerator -m  /Users/Desktop/metadata.xml -s API -cp SAP -dio  -d /Users/Desktop/app

Any suggestions?

evanireland
Advisor
Advisor
0 Kudos

Is one or more of the entities being filtered newly created on the client and doesn't exist in the backend? E.g. item (2) in the error message?

perage
Participant
0 Kudos

No, this happens when reading data from a struct that has already been filled with data from the service. I have a demo mode where this data is populated by a json file and it also happens for those data.

evanireland

Accepted Solutions (0)

Answers (1)

Answers (1)

evanireland
Advisor
Advisor
0 Kudos

Suggestions:

Write a loop that iterates over all the items in the list, and indicates which properties are set and which aren't, e.g.

for entity in commonData.productGroups { print("\(entity.canonicalURL)") for property in entity.entityType.structuralProperties { if !entity.hasDataValue(property) { print(" does not have value for \(property.name)") } }}

then you might enable payload tracing (provider.traceRequests = true, provider.traceWithData = true, provider.prettyTracing = true) and enable debug level logging for SAPOData. Perhaps the backend omits a value for the "Parent" property for some entities?

(The purpose of the above is just to understand the nature of the problem better - it isn't proposed as a fix or workaround.)