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 Answer 1

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
            )
        );
 }

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .