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