[SalesForce] System.FinalException: SObject row does not allow errors

Can someone point me in the direction of not getting the error

OpportunityTrigger: execution of AfterUpdate caused by: System.FinalException: SObject row does not allow errors: Trigger.OpportunityTrigger: line 34, column 1

trigger OpportunityTrigger on Opportunity (after delete, after insert, after undelete, after update, before delete, before insert, before update) {
    try {
        map<Id, Opportunity> sendVOCS = new map<Id, Opportunity>();
        map<id, Opportunity> stageChanged = new map<Id, Opportunity>();

        if (trigger.isAfter) {
            system.debug('OpportunityTrigger isAfter');
            if (trigger.isUpdate) {
                system.debug('OpportunityTrigger isAfter isUpdate');
                for (Opportunity record : trigger.newMap.Values()) {
                    Opportunity oldMapMatch = trigger.oldMap.get(record.Id);
                    if (record.StageName != oldMapMatch.StageName) {
                        // Voice of Customer Survey criteria
                        if (record.StageName == 'Closed - Awarded' || record.StageName == 'Closed - Lost') {
                            sendVOCS.put(record.Id, record);
                        }
                        // add newMap opportunity to a id/opp map
                        stageChanged.put(record.Id, record);
                    }
                }
                // send voice of customer surveys if they should be - criteria is above
                if (sendVOCS.keySet().Size() > 0) {
                    SendMail sendMail = new SendMail();
                    sendMail.SendVoiceOfCustomerSurvey(sendVOCS);
                    system.debug('Send Voice of Customer Surveys');
                }
                if (stageChanged.keySet().Size() > 0) {
                    StatusAndStageLogging statusAndStageLogging = new StatusAndStageLogging();
                    statusAndStageLogging.logOpportunityStage(stageChanged, trigger.oldMap);
                    system.debug('Log Opportunity Stage');
                }

                for (Opportunity opp : trigger.old){
                    opp.addError ('Opportunities can not be deleted');
                }
            }
        }
    }
    catch (exception e){
        ErrorHandler error = new ErrorHandler();
        error.logError(e);
    }
}

Best Answer

You are getting this error because of this below lines

for (Opportunity opp : trigger.old){ 
    opp.addError ('Opportunities can not be deleted'); 
}

Triggers can be used to prevent DML operations from occurring by calling the addError() method on a record or field. When used on Trigger.new records in insert and update triggers, and on Trigger.old records in delete triggers, the custom error message is displayed in the application interface and logged. More help i.e. Trigger Exceptions on this link.

You cannot use Trigger.Old to addError in After Update context.

You will have to surround that code of yours by checking the condition so that it runs only in before delete context. You will have to remove the above code from Trigger.IsUpdate and Trigger.isAfter condition and add a separate condition.

if(Trigger.IsDelete && Trigger.IsBefore){
    for (Opportunity opp : trigger.old){ 
        opp.addError ('Opportunities can not be deleted'); 
    }
}

It is always a best practice to check in which context your particular code should execute.

Related Topic