function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Mark SerloretiMark Serloreti 

Apex trigger error when sending E-Mail

Hello Community,
I am the marketing and business developer of a German iP Law Company. After our developer left, I was given the task to maintain our SF enterprise platform.
I turn to you with the following problem, that I encounter whenever I try to set a new task or send an e-mail. I assume that the error comes from a project that was started long before I joined the company, and was never really resolved and is now sitting there crippling our SF. Since I want to use SF for marketing campaigns, it is vital to me to have a working e-mail solution.

This is the error message:
Apex script unhandled trigger exception by user/organization: 005Dxxxxxx/00Dxxxxxxx

onTask: execution of AfterInsert

caused by: System.NullPointerException: Argument cannot be null.

Class.System.EncodingUtil.urlDecode: line 25, column 1
Class.TaskHandlers.AfterInsertHandler.handle: line 58, column 1
Class.Triggers.manage: line 58, column 1
Trigger.onTask: line 9, column 1

This is the on-screen error message:
Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger onTask caused an unexpected exception, contact your administrator: onTask: execution of AfterInsert

caused by: System.NullPointerException: Argument cannot be null.: Class.System.EncodingUtil.urlDecode: line 25, column 1


This is what I believe is the offending code:

trigger onTask on Task(after delete, after insert, after undelete, 
after update, before delete, before insert, before update) {
    
    new Triggers()
        .bind(Triggers.Evt.afterinsert, new TaskHandlers.AfterInsertHandler())
        .bind(Triggers.Evt.afterupdate, new TaskHandlers.AfterUpdateHandler())
        .bind(Triggers.Evt.beforeupdate, new TaskHandlers.BeforeUpdateHandler())
        .bind(Triggers.Evt.afterdelete, new TaskHandlers.AfterDeleteHandler()) 
        .manage();
}


SF support team suggested that I might post this error to the community, hoping to get help. I am not a developer, but I have experience in HTML5, JS, CSS3 and PHP.

Any help is highly appreciated! Thank you very much!
best regards,
Mark
Musunuru SurekhaMusunuru Surekha
Hello Mark,

Can you share the TaskHandlers class to further debug the issue?
Mark SerloretiMark Serloreti
I hope that this is the correct TaskHandler - I am not a developer, hence I have not really an idea about this. Please tell me what else you need. Thank you so very much!
Best regards,
Mark
 
/*Task handlers that process all trigger-side functionality*/
public with sharing class TaskHandlers 
{
    static boolean firstRunForBeforeInsert = true;
    static boolean firstRunForBeforeUpdate = true;
    static boolean firstRunForAfterInsert = true;
    static boolean firstRunForAfterUpdate = true;
    static boolean firstRunForAfterDelete = true;
     
    
    static String objectApiName { get; set; }
   // static Task2Document__c T2d { get; private set; }
   // static Integer sizeATIED {get; set;} 
     
    public class BeforeUpdateHandler implements Triggers.Handler  
    {
        public void handle() 
        {
            
        }
    }
      
    public class AfterInsertHandler implements Triggers.Handler  
    {
        public void handle() 
        {
            if (TaskHandlers.firstRunForAfterInsert) 
            {
                TaskHandlers.firstRunForAfterInsert = false;
                
                Map<Id, Task> triggerOldMap = (Trigger.oldMap != null) ? (Map<Id, Task>)Trigger.oldMap : new Map<Id, Task>();
                Map<Id, Task> triggerNewMap = (Trigger.newMap != null) ? (Map<Id, Task>)Trigger.newMap : new Map<Id, Task>();
            
                
                Set<ID> Taskids = new Set<ID>();
                Set<ID> Updatedids = new Set<ID>(); 
                
                Set<ID>  AllNotedIds = new Set<ID>();
                Set<ID>  AllDoneIds = new Set<ID>();
                Set<ID>  AllClosedIds = new Set<ID>();
                
                
               Map<Id, Document__c> NotedDocs = new Map<Id,  Document__c>();  
               List<Document__Share> newSharings = new List<Document__Share>();
                for(Task t : triggerNewMap.values())
                { 
                     
                     ///
                    Set<Id> checkboxIds = new Set<Id>();
                    String lastId = '';  
                    for(String idStr : EncodingUtil.urlDecode(t.DocumentIds__c, 'UTF-8').split(';'))
                    {
                        if (idStr instanceof Id)
                        {
                            checkboxIds.add(Id.valueOf(idStr));
                            lastId = idStr; 
                        }
                    }
                    Taskids.addAll(checkboxIds);
                    ///
                 ///get the objectApiName and according to that, create a new record on Task2Document with the respected field prepopulated///
                           //String recordId = (string)t.DocumentIds__c;  
                            
                           objectApiName = MetaDataUtil.getSobjectName(lastId.substring(0,3));  
                                        
                                        if(objectApiName == 'Document__c' || objectApiName == 'Register2Document__c')
                                        { 
                                             List<Document__Share> sharings = [Select Id From Document__Share Where RowCause = :Schema.Document__Share.RowCause.Task_related_Sharing__c AND UserOrGroupId = :triggerNewMap.get(t.Id).OwnerId];
                                            if(sharings != null && sharings.size() > 0)
                                                delete sharings;
                    
                                            Document__Share docShr = new Document__Share(UserOrGroupId = t.OwnerId, RowCause = Schema.Document__Share.RowCause.Task_related_Sharing__c, ParentId = lastId, AccessLevel = 'Edit');
                                            newSharings.add(docShr); 
                                            
                                           ///in order to get the Document Ids in the Task2Document__c Object///
                                                     
                                                      for(Document__c T2NotedDocs : [Select Id, Open_Tasks__c,  Completed_Tasks__c,  Closed_Tasks__c   From  Document__c Where  ID IN: Taskids])
                                                          {   
                                                               T2NotedDocs.Open_Tasks__c = 0;
                                                               T2NotedDocs.Completed_Tasks__c = 0;
                                                               T2NotedDocs.Closed_Tasks__c = 0;
                                                            
                                                               NotedDocs.put(T2NotedDocs.Id, T2NotedDocs);  
                                                               
                                                               Task2Document__c aT2D = new Task2Document__c (TaskId__c = t.Id, Document__c = T2NotedDocs.Id); 
                                                               insert aT2D;
                                                          } 
                                           ///  
                                        }
                                        
                                        if(objectApiName == 'File__c')
                                        { 
                                        Task2Document__c aT2D = new Task2Document__c (TaskId__c = t.Id, File__c = lastId ); 
                                        insert aT2D;  
                                        }
                                        
                                        if(objectApiName == 'Family__c')
                                        { 
                                        Task2Document__c aT2D = new Task2Document__c (TaskId__c = t.Id, Family__c = lastId); 
                                        insert aT2D;  
                                        }
                                        
                                        if(objectApiName == 'Portfolio__c')
                                        { 
                                        Task2Document__c aT2D = new Task2Document__c (TaskId__c = t.Id, Portfolio__c = lastId ); 
                                        insert aT2D;  
                                        }
                             
                 ///
                }
                if(newSharings.size() > 0)
                    insert newSharings;
                
                for(Task2Document__c T2doc : [Select TaskId__c  From Task2Document__c Where Document__c IN: NotedDocs.KeySet()])
                     {    
                         Updatedids.add(T2doc.TaskId__c) ;
                     } 
                for(Task OpenTaskNumber : [Select Id From Task Where Status =: 'Noted' AND Status != 'Proposal' AND Closed__c = False])
                     {    
                         AllNotedIds.add(OpenTaskNumber.Id) ;
                     }  
                     
                 for(Task DoneTaskNumber : [Select Id From Task Where Status =: 'Done' AND Status != 'Proposal' AND Closed__c = False])
                     {    
                         AllDoneIds.add(DoneTaskNumber.Id) ;
                     }
                     
                 for(Task ClosedTaskNumber : [Select Id From Task Where Closed__c = True])
                     {    
                         AllClosedIds.add(ClosedTaskNumber.Id) ;
                     }
                     
                    
                for(Task t : [Select Id, Status, Closed__c,  LinkedDocument__c, DocumentIds__c, WhatId From Task Where  Status =: 'Noted' AND Status != 'Proposal' AND Closed__c = False AND ID IN: Updatedids  ])
                {
                   // NotedDocs.get(t.DocumentIds__c).Open_Tasks__c++;
                   
                   List<Document__c> CurrentDocId = [Select Id  From  Document__c Where ID IN: NotedDocs.KeySet() LIMIT 1000];
                      Integer size = CurrentDocId.size();
                      for (Integer i = 0; i < size; i++)
                       {  
                         //NotedDocs.get(CurrentDocId.get(i).Id).Open_Tasks__c++; 
                         
                         List<Task2Document__c> ATIED = [Select TaskId__c From Task2Document__c Where Document__c =: CurrentDocId.get(i).Id AND TaskId__c IN:  AllNotedIds];  
                         Integer sizeATIED = ATIED.size();             
                         NotedDocs.get(CurrentDocId.get(i).Id).Open_Tasks__c = sizeATIED; 
                      }
                             
                }
                 
                
                 for(Task tOut : [Select Id, Status, Closed__c,  LinkedDocument__c,  WhatId From Task Where Status =: 'Done' AND Status != 'Proposal' AND Closed__c = False  AND ID IN: Updatedids  ])
                { 
                     List<Document__c> CurrentDocId = [Select Id  From  Document__c Where ID IN: NotedDocs.KeySet() LIMIT 1000];
                     Integer size = CurrentDocId.size();
                     for (Integer i = 0; i < size; i++)
                        {  
                           //NotedDocs.get(CurrentDocId.get(i).Id).Completed_Tasks__c++;
                           
                           List<Task2Document__c> ATIED = [Select TaskId__c From Task2Document__c Where Document__c =: CurrentDocId.get(i).Id AND TaskId__c IN:  AllDoneIds];  
                           Integer sizeATIED = ATIED.size();             
                           NotedDocs.get(CurrentDocId.get(i).Id).Completed_Tasks__c = sizeATIED;
                        } 
                          
                }
                 
                
                
                 for(Task tRem : [Select Id, Status, Closed__c, LinkedDocument__c, WhatId From Task Where  Closed__c = True  AND ID IN: Updatedids  ])
                {  
                    List<Document__c> CurrentDocId = [Select Id  From  Document__c Where ID IN: NotedDocs.KeySet() LIMIT 1000];
                    Integer size = CurrentDocId.size();
                       for (Integer i = 0; i < size; i++)
                            {  
                                //NotedDocs.get(CurrentDocId.get(i).Id).Closed_Tasks__c++;
                                
                                List<Task2Document__c> ATIED = [Select TaskId__c From Task2Document__c Where Document__c =: CurrentDocId.get(i).Id AND TaskId__c IN:  AllClosedIds];  
                                Integer sizeATIED = ATIED.size();             
                                NotedDocs.get(CurrentDocId.get(i).Id).Closed_Tasks__c = sizeATIED;
                            }
                }
                   
                if(NotedDocs.keySet().size() > 0)
                    update NotedDocs.values();
                 
                }
        }
    }
    
    public class AfterUpdateHandler implements Triggers.Handler
    {
        public void handle()
        {
            if(TaskHandlers.firstRunForAfterUpdate)
            {
                TaskHandlers.firstRunForAfterUpdate = false;
                 
                 
                Map<Id, Task> triggerOldMap = (Trigger.oldMap != null) ? (Map<Id, Task>)Trigger.oldMap : new Map<Id, Task>();
                Map<Id, Task> triggerNewMap = (Trigger.newMap != null) ? (Map<Id, Task>)Trigger.newMap : new Map<Id, Task>();
                
                
                Set<ID> Taskids = new Set<ID>();
                Set<ID> Updatedids = new Set<ID>();  
                
                Set<ID>  AllNotedIds = new Set<ID>();
                Set<ID>  AllDoneIds = new Set<ID>();
                Set<ID>  AllClosedIds = new Set<ID>();
                
                Map<Id, Task2Document__c> AvailableTasksInEachDoc = new Map<Id, Task2Document__c>(); 
                Map<Id, Document__c> NotedDocs = new Map<Id,  Document__c>(); 
                 
                List<Document__Share> newSharings = new List<Document__Share>();
                for(Task t : triggerNewMap.values())
                {
                    
                     ///
                    Set<Id> checkboxIds = new Set<Id>();
                    String lastId = '';  
                    for(String idStr : EncodingUtil.urlDecode(t.DocumentIds__c, 'UTF-8').split(';'))
                    {
                        if (idStr instanceof Id)
                        {
                            checkboxIds.add(Id.valueOf(idStr));
                            lastId = idStr; 
                        }
                    }
                    Taskids.addAll(checkboxIds);
                    ///
                    
                    
                    if(t.OwnerId != triggerOldMap.get(t.Id).OwnerId)
                    {
                        List<Document__Share> sharings = [Select Id From Document__Share Where RowCause = :Schema.Document__Share.RowCause.Task_related_Sharing__c AND UserOrGroupId = :triggerOldMap.get(t.Id).OwnerId];
                        if(sharings != null && sharings.size() > 0)
                            delete sharings;

                        Document__Share docShr = new Document__Share(UserOrGroupId = t.OwnerId, RowCause = Schema.Document__Share.RowCause.Task_related_Sharing__c, ParentId = lastId, AccessLevel = 'Edit');
                        newSharings.add(docShr);
                    }
                      
                    
                }
                if(newSharings.size() > 0)
                    insert newSharings;
                  
                  
                  
                  for(Document__c T2NotedDocs : [Select Id, Open_Tasks__c,  Completed_Tasks__c,  Closed_Tasks__c   From  Document__c Where  ID IN: Taskids])
                      {   
                         T2NotedDocs.Open_Tasks__c = 0;
                         T2NotedDocs.Completed_Tasks__c = 0;
                         T2NotedDocs.Closed_Tasks__c = 0;
                                                            
                         NotedDocs.put(T2NotedDocs.Id, T2NotedDocs);  
                      }                                    
                          
                 for(Task2Document__c T2doc : [Select TaskId__c  From Task2Document__c Where Document__c IN: NotedDocs.KeySet()])
                     {    
                         Updatedids.add(T2doc.TaskId__c) ;
                     }  
                 
                 for(Task OpenTaskNumber : [Select Id From Task Where Status =: 'Noted' AND Status != 'Proposal' AND Closed__c = False])
                     {    
                         AllNotedIds.add(OpenTaskNumber.Id) ;
                     }  
                     
                 for(Task DoneTaskNumber : [Select Id From Task Where Status =: 'Done' AND Status != 'Proposal' AND Closed__c = False])
                     {    
                         AllDoneIds.add(DoneTaskNumber.Id) ;
                     }
                     
                 for(Task ClosedTaskNumber : [Select Id From Task Where Closed__c = True])
                     {    
                         AllClosedIds.add(ClosedTaskNumber.Id) ;
                     }

                 
                 
                for(Task t : [Select Id, Status, Closed__c,  LinkedDocument__c, WhatId From Task Where  Status =: 'Noted' AND Status != 'Proposal' AND Closed__c = False  AND ID IN: Updatedids   ])
                {                                
                      List<Document__c> CurrentDocId = [Select Id  From  Document__c Where ID IN: NotedDocs.KeySet() LIMIT 1000];
                      Integer size = CurrentDocId.size();
                      for (Integer i = 0; i < size; i++)
                       {  
                         //NotedDocs.get(CurrentDocId.get(i).Id).Open_Tasks__c++; 
                         
                         List<Task2Document__c> ATIED = [Select TaskId__c From Task2Document__c Where Document__c =: CurrentDocId.get(i).Id AND TaskId__c IN:  AllNotedIds];  
                         Integer sizeATIED = ATIED.size();             
                         NotedDocs.get(CurrentDocId.get(i).Id).Open_Tasks__c = sizeATIED; 
                      }
                                               
                }
                 
                
                 
                
                for(Task tOut : [Select Id, Status, Closed__c,  LinkedDocument__c,  WhatId From Task Where Status =: 'Done' AND Status != 'Proposal' AND Closed__c = False  AND ID IN: Updatedids  ])
                { 
                     List<Document__c> CurrentDocId = [Select Id  From  Document__c Where ID IN: NotedDocs.KeySet() LIMIT 1000];
                     Integer size = CurrentDocId.size();
                     for (Integer i = 0; i < size; i++)
                        {  
                           //NotedDocs.get(CurrentDocId.get(i).Id).Completed_Tasks__c++;
                           
                           List<Task2Document__c> ATIED = [Select TaskId__c From Task2Document__c Where Document__c =: CurrentDocId.get(i).Id AND TaskId__c IN:  AllDoneIds];  
                           Integer sizeATIED = ATIED.size();             
                           NotedDocs.get(CurrentDocId.get(i).Id).Completed_Tasks__c = sizeATIED;
                        } 
                          
                }
                 
                
                
                 for(Task tRem : [Select Id, Status, Closed__c, LinkedDocument__c, WhatId From Task Where  Closed__c = True  AND ID IN: Updatedids  ])
                {  
                    List<Document__c> CurrentDocId = [Select Id  From  Document__c Where ID IN: NotedDocs.KeySet() LIMIT 1000];
                    Integer size = CurrentDocId.size();
                       for (Integer i = 0; i < size; i++)
                            {  
                                //NotedDocs.get(CurrentDocId.get(i).Id).Closed_Tasks__c++;
                                
                                List<Task2Document__c> ATIED = [Select TaskId__c From Task2Document__c Where Document__c =: CurrentDocId.get(i).Id AND TaskId__c IN:  AllClosedIds];  
                                Integer sizeATIED = ATIED.size();             
                                NotedDocs.get(CurrentDocId.get(i).Id).Closed_Tasks__c = sizeATIED;
                            }
                }
                   
                if(NotedDocs.keySet().size() > 0)
                    update NotedDocs.values();
            }
        }
         
    }
    
    
    
    public class AfterDeleteHandler implements Triggers.Handler  
    {
        public void handle() 
        {
             if(TaskHandlers.firstRunForAfterDelete)
            {
                TaskHandlers.firstRunForAfterDelete = false; 
                
                Map<Id, Task> triggerOldMap = (Trigger.oldMap != null) ? (Map<Id, Task>)Trigger.oldMap : new Map<Id, Task>(); 
               
                
            }
            
        }
    }
    
    
}

 
Musunuru SurekhaMusunuru Surekha
Before this for loop try to check null condition.
if(t.DocumentIds__c ! = null){
for(String idStr : EncodingUtil.urlDecode(t.DocumentIds__c, 'UTF-8').split(';')) { if (idStr instanceof Id) { checkboxIds.add(Id.valueOf(idStr)); lastId = idStr; } }
}