2

I have a trigger on "Opportunity" object which on record update also updates it "OpportunityLineItem" records. We have a validation rule on "OpportunityLineItem" that if a field is blank the error should be thrown.

Now in my org we have many "Opportunity" records with its corresponding "OLI" records with that field as blank.

So now whenever the trigger fires we receive an exception like below.

enter image description here

Is there any way to handle this exception in a more refined way something like below ?

enter image description here

Below is the trigger code and class.

trigger Opportunity_CloseDate_Update on Opportunity (after update) {

    OpportunityProductScheduleHelper helper = new OpportunityProductScheduleHelper();

  if (Trigger.isUpdate) {
        helper.doUpdate(Trigger.newMap, Trigger.oldMap);
    }

}

Trigger Class

public with sharing class OpportunityProductScheduleHelper {

    public OpportunityProductScheduleHelper() {

    }

    // On Update, send all Opportunities for FAE and Manufacturer Rep to the GSM for Approval when the StageName
    // changes to 'Stage 3'
    public void doUpdate(Map<Id, Opportunity> newmap, Map<Id, Opportunity> oldmap) {
      //Check the opportunites in the trigger to see if the Close Date changed. 
    //if so add them to a Set
  Integer Days_Shifted;

  List<OpportunityLineItem> OppLineItemList = new List<OpportunityLineItem>();

  for (Opportunity newOpp: newmap.values()) {

    Opportunity oldOpp = oldmap.get(newOpp.id);

     if(newOpp.CloseDate <> oldOpp.CloseDate){
      Days_Shifted = oldOpp.CloseDate.daysBetween(newOpp.CloseDate);
      List<OpportunityLineItem> LineItemList = [SELECT id, ServiceDate, OpportunityId FROM OpportunityLineItem WHERE OpportunityId =:newOpp.id];

            for(OpportunityLineItem OppLine : LineItemList){
                OppLine.ServiceDate = newOpp.CloseDate;
                OppLineItemList.add(OppLine);

        updateSchedule(Days_Shifted, OppLine.Id);
            //Now here for each opportunity line item schedule item.
            for(OpportunityLineItemSchedule opplsched : OppLine.OpportunityLineItemSchedules){

               system.debug('Going to shift :' + opplsched.Id + ' ' + Days_Shifted + ' days.');
                } 
            }

       }
    }
          //update the line items
        if(!OppLineItemList.isEmpty()){
            update OppLineItemList;    //This is line 40

        }
    }

    private void updateSchedule(Integer Days_Shifted, Id OppLineItemId){

    List<OpportunityLineItemSchedule> OldScheduleLines = [SELECT id, ScheduleDate, OpportunityLineItemId FROM OpportunityLineItemSchedule WHERE OpportunityLineItemId =:OppLineItemId];

    for(OpportunityLineItemSchedule OppSchedLine : OldScheduleLines){
        OppSchedLine.ScheduleDate = OppSchedLine.ScheduleDate + Days_Shifted;
    }

    //update the scheduledates
        if(!OldScheduleLines.isEmpty()){
            update OldScheduleLines;
        }

    }
}

Please let me know any way to achieve this.

3 Answers 3

3

put these line in try catch

if(!OppLineItemList.isEmpty()){
            update OppLineItemList;    //This is line 40
}

something like

    try {
    if(!OppLineItemList.isEmpty()){
                    update OppLineItemList;    //This is line 40
        }
    }
    catch(exception ex) {
      //display custom message
      trigger.New[0].adderror('Your custom message');
      break;
    }

It will help you. Or in handler pass your trigger. new list and then

OppLineItemList[0].adderror('Your custom message');

Update: Or you can try one thing

Integer count = 0;
Database.SaveResult[] srList = Database.update(OppLineItemList, false);
for (Database.SaveResult sr : srList) {
     if (!sr.isSuccess()) 
          for(Database.Error err : sr.getErrors())
                 OppLineItemList[count].adderror('Your custom message or can use err.getMessage()');
    count++;
} 

it will give you error on that particular record and will work as excepted with bulk records

1
  • The use of trigger.new[0] does not seem a proper mapping mechanism. In fact it is downright wrong to recommend. You should fix.
    – Adrian Larson
    Oct 4, 2016 at 5:36
0

Insert of just update you can use Database.update(List<sObject>) method.

That will return you Database.SaveResult (or list of them ) that will contain all the errors if they are

Here is more information about https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_database.htm#apex_System_Database_update

1
  • It doesn't return SaveResult unless you do a partial operation, which requires another parameter...
    – Adrian Larson
    Oct 4, 2016 at 5:38
0

To utilize the validation rule message you surround your DML operation with

try{
   // DML OPERATION
}catch(DmlException e){
   Trigger.New[0].addError(e.getDmlMessage(0));  // This will display your custom validation rule error messages
   break;    
}

You must log in to answer this question.

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