0

I have an ApexDebugLog class that logs errors by creating a record in my own custom object when something goes wrong. In 2 separate batch classes I'm using this logging class to log errors. If I just pass a short, simple string into my long text area fields in my logging custom object, everything works well.

The problem is that I really want to pass in a list of ids converted to a string into that field so that I can see all the ids that the operation failed on. When I do this using String.valueOf(listOfids), I get the first 10 ids and then a "..." and that's it. If I try other things like string.join(listOfids,',') or serializePretty into a JSON and then deserialize, the record doesn't come through at all.

Can anyone explain what is going on here and how I can get my entire list of ids into my long text area field? (Max length is 10,000 characters).

Here's the logging class (taken from https://gist.github.com/miragedeb/70d5b70a6f73c8530db7):

global class ApexDebugLog {
    /*
        A Virtual Class that Defines the 
        Structure of a Log
    */
    public virtual class Log{
        public String Type;
        public String ApexClass;
        public String Method;

        public String RecordId;
        public String Message;
        public String StackTrace;
    }
    
    /*
        A Class that Extends the Virtual Class - Log
        to define a log of type - Error
    */
    public class Error extends Log{
        public Error(String cls, String routine, String recId, Exception ex){
            this.Type = 'Error';
            this.ApexClass = cls;
            this.Method = routine;
            this.RecordId = recId;
            this.Message = ex.getMessage();
            this.StackTrace = ex.getStackTraceString();
        }
    }

    /*
        A Class that Extends the Virtual Class - Log
        to define a log of type - Information
    */
    public class Information extends Log{
        public Information(String cls, String routine, String recId, String msg){
            this.Type = 'Information';
            this.ApexClass = cls;
            this.Method = routine;
            this.RecordId = recId;
            this.Message = msg;
            this.StackTrace = NULL;
        }
    }
    /*
        A Public Method that can be utilized by
        other Apex Classes to create a record into
        the Apex Debug Log object stating the Error
        or Information.
    */
    public void createLog(Log logToCreate){
        try{
            /*
                Ensure that we're well within the Governor Limits.
                The creation of the Log shouldn't disturb the execution
                of that Apex Class that utilizes this method to
                create a log.
            */
            if(
                (Limits.getDMLRows() < Limits.getLimitDMLRows()) && 
                (Limits.getDMLStatements() < Limits.getLimitDMLStatements())
            )
            {
                Apex_Debug_Log__c apexDebuglog = new Apex_Debug_Log__c(
                    Type__c         = logToCreate.Type,
                    Apex_Class__c   = logToCreate.ApexClass,
                    Method__c       = logToCreate.Method,
                    Record_Id__c    = logToCreate.RecordId,
                    Message__c      = logToCreate.Message,
                    Stack_Trace__c  = logToCreate.StackTrace
                );

                Database.insert(apexDebuglog, FALSE);
            }
            else{
                System.debug('The Governor Limits have already been exhausted and hence failed to create a Log!');
            }
        }
        catch(DMLException ex){
            System.debug('Something fatal has occurred and hence failed to create a Log! Error:' + ex.getMessage());
        }
    }
}

Here's an example usage in my batch class of this class. I have a private method that I use to convert the ids into a string and then I send that into the logging class.

    private String convertToIds(List<sObject> inputList)
    {
        List<Id> ids = new List<Id>();
        for(sobject so:inputList)
        { 
            ids.add(so.id);
        }
        return 'testString';
        //return string.join(ids,',');
        //return String.valueOf(ids);  //JSON.serializePretty(ids);
    }

....
try{
            insert exportRecords;
        }
        catch(Exception e){
            new ApexDebugLog().createLog(
                new ApexDebugLog.Error(
                    'KlitaSyncBatchClass',
                    'execute - insert to Misrad_Haklita_Export__c',
                    convertToIds(exportRecords),
                    e
                )
            );
        }
1

So, your problem is that if you fail to insert records, there aren't any ids to work with

try{insert exportRecords;}
catch(Exception e){
     new ApexDebugLog().createLog(
           new ApexDebugLog.Error(
                'KlitaSyncBatchClass',
                'execute - insert to Misrad_Haklita_Export__c',
                convertToIds(exportRecords), // exportrecords have no ids!
                e
            )
        );
 }

if you were updating records, then you could do this:

try{update exportRecords;}
catch(Exception e){
     new ApexDebugLog().createLog(
           new ApexDebugLog.Error(
                'KlitaSyncBatchClass',
                'execute - update to Misrad_Haklita_Export__c',
                JSON.serialize(new Map<Id,SObject>(exportRecords).keySet()),
                e
            )
        );
 }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.