Saturday 26 January 2013

Salesforce System Error: 1148877694-2467 (681892207) (681892207) when using JSON generator class in apex

Today i encountered a very interesting error when i was using JSON generator .The error said FATAL_ERROR System.UnexpectedException: Salesforce System Error: 1148877694-2467 (681892207) (681892207).

Looking into the error my first thing was to run through my code again and again .I referred the following documents on JSON generator class 



The code in my eyes look pretty simple and here is the exact snippet that was throwing the exception

JSONGenerator gen = JSON.createGenerator(true);
gen.writeStartObject();
gen.writeNumberField('abc', 1.21);
gen.writeStringField('def', 'xyz');
String pretty = gen.getAsString();//This statement use at the end only .It ends the JSON 
System.debug('STRING JSON'+pretty);
gen.writeStartObject();
gen.writeStringField('def', 'xyz');
gen.writeEndObject();

After the line 6 (where i am printing the log )i have the following statement in my debug log 13:24:03:048 FATAL_ERROR System.UnexpectedException: Salesforce System Error: 1148877694-2467 (681892207) (681892207)

I decided to read the document again and discovered that the when i use the method getAsString method of JSON generator class the apex automatically closes the JSON and hence attempting to start writing the Object after closing generates an error .

Though this is simple issue but the error message is not caught properly in the salesforce backend .

So the conclusion is always using getAsString of JSON generator class should be practiced .

Never use it even for the debug statements.

This is one of the rare cases where error message is misleading.Hope this helps for people trying to google and find why the error is occuring when using JSON generator.

Just commmenting Line 5 and line 6 will resolve the issue.
Happy Coding !

Tuesday 22 January 2013

JSON.serialize in APEX after launch of API 27.0(Spring 13)


These days i spend lot of time on Stackexchange  for salesforce.This has been amazing site for salesforce queries related to admin or development .

Very interesting changes after API 27.0 was launched in JSON.serialize system method of salesforce .This method is used to convert the apex objects (primitive or User defined ) into the JSON string format.Quite helpful in integration if structure of JSON is pretty simple then forming apex class and using JSON.serialize helps to get the JSON body for making the POST call to the external system.

There are some changes on how this behaves after launch of the Spring 13 API.Here is the reference to the stackexchange links from where i gathered this information and thought of blogging so that it may help others.

http://salesforce.stackexchange.com/questions/6192/json-serialize-method-not-returning-null-fields

http://salesforce.stackexchange.com/questions/7493/json-serialize-is-not-working-in-winter-13

So i thought of experimenting on this with the small test code

Here is the code

The first query pulls an account that has fax ,website field with no data .In short these are null for the Account thats considered in the below example

public class dummy{

    public static void dummytest(){
    Account acc= [Select Name, id, Fax, Website from account where id ='001Z000000J0w5C'];
    system.debug('JSON OF OBJECT FROM SALESFORCE SCHEMA'+JSON.Serialize(acc));
    
    dummywrapp dmy= new dummywrapp();
    dmy.Name='Test';    
    System.debug('JSON FROM APEX CREATED OBJECT'+JSON.serialize(dmy));
    }
    
    public class dummywrapp{
    
    public string Name;
    public string Location;
    
        }

}


DEBUG LOG
_________



21:23:17:122 USER_DEBUG [5]|DEBUG|JSON OF OBJECT FROM SALESFORCE SCHEMA{"attributes":{"type":"Account","url":"/services/data/v26.0/sobjects/Account/0019000000KANkZAAX"},"Name":"Mobile Test","Id":"0019000000KANkZAAX"}


21:23:17:124 USER_DEBUG [9]|DEBUG|JSON FROM APEX CREATED OBJECT{"Name":"Test","Location":null}


The following conclusion can be drawn looking at the debug log.

 When using JSON.serialize with objects bounded to apex schema if the field has blank values the KEY and Value in output of JSON is ignored While same does not hold good for objects formed through class formation from apex. 

 Not sure if in future salesforce changes this but certainly this information is good to know when we are integrating any system that uses JSON to communicate and if JSON.serialize is the mechanism to generate the JSON.

 Play safe with JSONserialize() method !

References

http://salesforce.stackexchange.com/questions/6192/json-serialize-method-not-returning-null-fields

Saturday 12 January 2013

TimeZone Methods of Spring 13(API 27.0 ) release of salesforce


The timezone handling in apex was not so elegant and as a developer we had difficult times converting the GMT time zone to the locale time zone in apex language
The below code snippet demonstrates the earlier technique i had to use to convert the GMT time into the local time of the user
String timeZone = [select timeZoneSidKey from User where id=:userinfo.getUserId()].timeZoneSidKey;
System.debug('TIME ZONE '+timeZone);
Datetime dateGMT=Datetime.newInstanceGmt(2013,01,12,01,12,0);//Form the GMT time and date in sfdc
String formatteddate=dateGMT.format('yyyy-MM-dd HH:mm:ss',timeZone);//format the GMT into the Local according to his TimeZone Key
System.debug('LOCAL  TIME ....'+Datetime.valueOfGmt(formatteddate));

Debug Log
02:55:43.119 (119313000)|USER_DEBUG|[2]|DEBUG|TIME ZONE America/Los_Angeles
02:55:43.119 (119662000)|VARIABLE_ASSIGNMENT|[3]|dateGMT|"2013-01-12T01:12:00.000Z"
02:55:43.120 (120138000)|USER_DEBUG|[5]|DEBUG|LOCAL  TIME ....2013-01-11 17:12:00

debug Log analysis
  Number of SOQL queries: 1 out of 100
  Number of query rows: 1 out of 50000
Thanks to the spring 13 apex feature .No more i need query to find the TimeZoneSidKey Here is how i will structure my new code with the help of new time Zone methods
String timeZone = UserInfo.getTimeZone().getID();
System.debug('TIME ZONE'+timeZone);
Datetime dateGMT=Datetime.newInstanceGmt(2013,01,12,01,12,0);//Form the GMT time and date in sfdc
String formatteddate=dateGMT.format('yyyy-MM-dd HH:mm:ss',timeZone);//format the GMT into the Local according to his TimeZone Key
System.debug('LOCAL  TIME ....'+Datetime.valueOfGmt(formatteddate));

Debug Log
02:55:43.119 (119313000)|USER_DEBUG|[2]|DEBUG|TIME ZONE America/Los_Angeles
02:55:43.119 (119662000)|VARIABLE_ASSIGNMENT|[3]|dateGMT|"2013-01-12T01:12:00.000Z"
02:55:43.120 (120138000)|USER_DEBUG|[5]|DEBUG|LOCAL  TIME ....2013-01-11 17:12:00
debug Log analysis
Number of SOQL queries: 0 out of 100
Number of query rows: 0 out of 50000

So we have saved a query and also a query row using the native userinfo.getTimezone() Method .

 Whats more interesting is Timezone system class in apex now is capable of providing accurate offset from GMT .(I may not need to maintain any custom setting to know the offset depending on timezone of the user)

 The key points to note are as follows:

   1)The negative or positive sign is indicated while returning the integer on   userinfo.gettimezone.getOffset(DateTime);
 2)The integer is in milliseconds .


References: 

 1)http://developer.force.com/releases/release/Spring13
 2)Realease Notes Spring 13 Pdf

Introducing Lightning Base Components

Lightning Base Components are great addition to the platform and in fact revolutionary .One of the concerns around lightning component ...