0

Background:

  1. I have trigger on Opportunity object for after delete event and it updates a field Number_of_Opps__c on Account object.
  2. There is a validation rule on Account object for the same field firing if Number_of_Opps__c = 0
  3. When I am deleting Opportunity record from custom lightning component,trigger on Opportunity is running and it is updating field Account.Number_of_Opps__c to zero but validation rule on Account object is rejecting this update.

Problem: When this happens, I need to show user a simple and clean message without stacktrace of trigger line number.

My observation:

  1. If Apex trigger is not involved then it is displaying clean message to the user without stacktrace of line numbers.

I have gone through Error Handling Best Practices for Lightning and Apex but no luck.

As a last resort, I have tried to use regex to replace everything after : [] and even that is not working, maybe something wrong with my regex.

Here is the code:

HelloWorld.cmp

<aura:component controller="HelloWorldApexController">
    <button onclick="{!c.delete}">Delete</button>
</aura:component>

HelloWorldController.js:

({
    delete: function(cmp) {
        var action = cmp.get("c.deleteOpp");
        action.setCallback(this, function(result) {
            if(result.getState() == 'SUCCESS'){

            }
            if(result.getState() == 'ERROR'){
                var toast = $A.get("e.force:showToast");
                if(toast){
                    toast.setParams({
                        "title": "Error",
                        "message": result.getError()[0].message
                    });
                }
                toast.fire();
            }
        });
        $A.enqueueAction(action);
    }
})

HelloWorldApexController.cls:

public with sharing class HelloWorldApexController {

    @AuraEnabled
    public static void deleteOpp(){
        Opportunity oppObj = new Opportunity(Id='006370000025PVY');

        try{
            delete oppObj;  
        }catch(DmlException e){
            throw new AuraHandledException(e.getDmlMessage(0).replaceFirst(': \\[\\] .*',''));
        }
    }
}

OpportunityTrigger.trigger:

trigger OpportunityTrigger on Opportunity (after delete) {

    if(trigger.isAfter && trigger.isDelete){
        Account accObj = new Account(Id = '00137000002KXpBAAW',Number_of_Opps__c = 0);
        update accObj;
    }

}

Note: For the sake of simplicity, I have hardcoded Ids and did not bulkify the trigger.

Screenshot:

enter image description here

3
  • 1
    Honestly, you're asking about the wrong problem. You should be designing each trigger in a way that will absolutely only ever use addError and not throw an exception. It's 100% possible to do this 100% of the time. Learning how to write proper triggers is essential.
    – sfdcfox
    Jul 25, 2018 at 1:36
  • @sfdcfox I agree. Client is extensively using declarative rollup summary tool for calculating rollups and it is stemming from dlrs package and not in my control.
    – javanoob
    Jul 25, 2018 at 1:46
  • @sfdcfox I see others also ran into same issue and there is no solution yet : salesforce.stackexchange.com/questions/209703/…
    – javanoob
    Jul 25, 2018 at 1:47

3 Answers 3

3

Even if you can't control other people's code, you can control your own. You should be able to do this:

Database.SaveResult result = Database.delete(oppObj, false);
if(!result.isSuccess()) {
  throw new AuraHandledException(result.getErrors()[0].getMessage());
}

You will no longer get DmlException messages, but instead get a nice interface to render an error with. If you still need to contend with other types of errors (e.g. a NullPointerException), you can wrap up the entire thing and rethrow:

try {
  Database.SaveResult result = Database.delete(oppObj, false);
  if(!result.isSuccess()) {
    throw new AuraHandledException(result.getErrors()[0].getMessage());
  }
} catch(Exception e) {
  throw new AuraHandledException(e.getMessage());
}
5
  • Thanks but It didn't work. Here is the video showing the change I made as per your suggestion and the result: vimeo.com/281628694 If you have time, you can take a look at the complete code I uploaded on gist : gist.github.com/sfdcnoob/4c686babb21d82e65d2fea11e3288cae Thanks again.
    – javanoob
    Jul 25, 2018 at 14:29
  • @javanoob That's not the experience I get... When I installed your code, I get "55invalid reference id" when testing. You might be dealing with a caching issue.
    – sfdcfox
    Jul 25, 2018 at 15:01
  • Did you update the hard-coded ids in the controller and trigger? "55Invalid reference Id" seems to be because of that. Thanks for trying my code.
    – javanoob
    Jul 25, 2018 at 15:03
  • @javanoob Huh. Yeah, after updating, it works that way now. Realistically, then, I don't think there's a foolproof way of doing it except to fix the code that's misbehaving. As far as your regex, I'm guessing that there's some newlines/alternative whitespace that's messing your regex up. Maybe: :\\s+\\[\\]\\s+.* might work better?
    – sfdcfox
    Jul 25, 2018 at 15:14
  • Thanks. The regex you suggested worked and it is not showing stacktrace of line numbers. I see an open issue(github.com/afawcett/declarative-lookup-rollup-summaries/issues/…) on DLRS github, requesting for allOrNone flag to false. In conclusion, I can get it the way I want, only if I have access to the trigger that is doing the actual DML on the failing record. Thank you again for taking time to look into this.
    – javanoob
    Jul 25, 2018 at 15:39
5

You shouldn't need to parse the message with regex. The getDmlMessage(i) method gives you the 'pretty' message output without the stack trace details.

In the example below, I created a validation rule on the Account object that throws an exception if the Account Number field has been changed.

Error Condition Formula: ISCHANGED( AccountNumber )

Error Message: Cannot change account number


Component

<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes" 
                access="global" 
                controller="q226338Controller">

    <lightning:notificationsLibrary aura:id="notifLib"/>
    <button onclick="{!c.updateAccount}">Update Account Number</button>

</aura:component>

Controller

({
    updateAccount: function (component, event, helper) {
        var action = component.get("c.updateAccountNumber");
        action.setCallback(this, function (result) {
            if (result.getState() == 'SUCCESS') {
                console.log('success?');
            }
            if (result.getState() == 'ERROR') {
                component.find('notifLib')
                    .showToast({
                        "title": "Error!",
                        "message": result.getError()[0].message
                    });
            }
        });
        $A.enqueueAction(action);
    }
})

Apex Controller

public with sharing class q226338Controller {

    @AuraEnabled
    public static void updateAccountNumber() {
        String newNumber = String.valueOf(Integer.valueOf(Math.random() * 2000));

        Account a = new Account(Id = 'hardcoded value', 
                               AccountNumber = newNumber);

        try {
            update a;
        } catch (DmlException ex) {
            throw new AurahandledException(ex.getDmlMessage(0));
        } catch (Exception ex) {
            throw new AurahandledException(ex.getMessage());
        }
    }
}

And the result: enter image description here

The pretty error message output can also be seen here: Built-In Exceptions and Common Methods

1
  • 1
    It looks similar to my problem but it is slightly different. In my case, DML began in Apex controller but exception occured in trigger because of that getDmlMessage(0) is returning complete stacktrace. I found similar unanswered question here : salesforce.stackexchange.com/questions/209703/…
    – javanoob
    Jul 24, 2018 at 22:03
2

I think that simpliest solution will be creating customer label and placing it in the AuraHandledException.

 throw new AuraHandledException(Label.YourException);
1
  • Thanks. I am confused as why my regex approach also not working. Do you see anything wrong there?
    – javanoob
    Jul 24, 2018 at 18:19

You must log in to answer this question.

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