[SalesForce] deserializeStrict method: bug

The documentation about the deserializeStrict method in JSON class is (emphasis added):

All attributes in the JSON string must be present in the specified type. If the JSON content contains attributes not present in the System.Type argument, such as a missing field or object, deserialization fails in some circumstances. When deserializing JSON content with extraneous attributes into an Apex class, this method throws an exception in all API versions. However, no exception is thrown when you use this method to deserialize JSON content into a custom object or an sObject.

I wrote this code to test it:

String jsonString = '{"first":"value1", "second":"value2", "third":"value3"}';
Account c = (Account)JSON.deserializeStrict(jsonString, Account.class);
System.debug(c);`

And I receive this exception:

Exception: System.JSONException: No such column 'first' on sobject of type Account
StackTrace: Class.System.JSON.deserializeStrict: line 19, column 1
AnonymousBlock: line 2, column 1
AnonymousBlock: line 2, column 1
LINE: 19 COLUMN: 1

Reading the documentation I understand that no exception is thrown when you use this method to deserialize JSON content into a custom object or an sObject. Is this interpretation correct or not?

Best Answer

Aside from that last sentence the documentation is spot on. However, I would argue that the behavior is correct, and it is just that sentence which is flawed.


It is easy to demonstrate that for a custom object, it is flat out incorrect. What they mean is an instance of a custom defined class. Let's check:

Script

class Demo { }
Demo instance = (Demo)JSON.deserializeStrict('{"first": 1}', Demo.class);

Error

System.JSONException: Unknown field: Demo.first

Sure does throw.


It's a little trickier to demonstrate with an sObject, however. Sure, it throws an error with a concrete sObjectType, but it could in theory work for a generic instance.

Script

String payload = '{"first": 1}';
SObject record = (SObject)JSON.deserializeStrict(payload, SObject.class);

Error

System.JSONException: Nested object for polymorphic foreign key must have an attributes field before any other fields.

Okay...let's try adding that attribute:

Script

String payload = '{"attributes": {}, "first": 1}';
SObject record = (SObject)JSON.deserializeStrict(payload, SObject.class);

Error

System.JSONException:

Hmm...not that helpful. Let's try specifying a valid attributes value.

Script

String payload = '{"attributes":{"type":"Account"}, "first": 1}';
SObject record = (SObject)JSON.deserializeStrict(payload, SObject.class);

Error

System.JSONException: No such column 'first' on sobject of type Account

Back to the same error we had when it was a specific sObjectType.

Just to be sure, we can also try it with a custom sObjectType.

Script

MyObject__c record = (MyObject__c)JSON.deserializeStrict('{"first": 1}', MyObject__c.class);

Error

System.JSONException: No such column 'first' on sobject of type MyObject__c

So it looks like the documentation is in fact incorrect in that last sentence.