0

I want to prevent DML operations during certain processing-situations and provoke a Database.SaveResult with an Database.Error[]-List.

According to SObject class documentation, the method addError() should "prevent any DML operation from occurring". As it turns out, this is not true. The following code commits the record to the database without any errors.

Account a = new Account(Name = 'Valid Corp Name Ltd.');
a.addError('Error one');
a.addError('Error two');
Database.SaveResult sr = Database.insert(a, false);
System.debug(sr.isSuccess());
System.debug(sr.getErrors());

Debug log:

16:11:01:548 USER_DEBUG [5]|DEBUG|true
16:11:01:548 USER_DEBUG [6]|DEBUG|()

How can I prevent a record from beeing commited? I am aware of the similar question sObject.addError did not prevent dml operation, which did not get answered. So I am trying again.

3
  • 1
    r u using above code inside trigger or just anonymous/Method Block? i think addError need to used against in Trigger operations
    – sdandamud1
    Jun 7, 2019 at 14:16
  • 2
    Possible duplicate: Does addError() work outside of triggers?
    – Adrian Larson
    Jun 7, 2019 at 14:27
  • yes, it can be considered a duplicate. I was not aware, that addError actually only works in trigger context, therefore I assumed the question was different. Jun 7, 2019 at 14:32

2 Answers 2

4

From the documentation addError(errorMsg) Marks a trigger record with a custom error message and prevents any DML operation from occurring.

So you can only this method in trigger context. In your example, a is just a variable and is not part of trigger context (i.e. trigger.new).

if you would do something like trigger.new[0].addError('Some error'), then changes to trigger.new[0] won't be commited.

Hope, it helps.

Edit: In the referenced question, there is an answer. It just wasn't accepted for some reason (https://salesforce.stackexchange.com/a/82421/16508).

1
  • Thank you for clarification. Was not aware that this only works in trigger context. Jun 7, 2019 at 14:21
1

Copying my answer from Does addError() work outside of triggers? as this is basically the same question.


It only works on trigger context records, but it can be applied to those records outside of a trigger. You cannot call this method on a record which is not yet in a trigger context, then have the error carry through to the trigger context.

This code won't prevent DML:

Account record = new Account();
record.addError('You cannot insert this record');
insert record;

However, this code will:

trigger Account on Account (before insert)
{
    PreventDml.validate(trigger.new);
}
public with sharing class PreventDml
{
    public void validate(List<SObject> records)
    {
        for (SObject record : records)
        {
            record.addError('You cannot insert this record');
        }
    }
}

If you are trying to test this code, the only realistic, effective way to make sure it does what you want is to run the trigger. For example, in this scenario I might have a test like:

@IsTest
class AccountTriggerTests
{
    @IsTest static void testPreventDml()
    {
        DmlException expectedException;
        Test.startTest();
            try
            {
                insert new Account();
            }
            catch (DmlException dmx)
            {
                expectedException = dmx;
            }
        Test.stopTest();

        system.assertNotEquals(null, expectedException,
            'You should not be able to insert any Account');
        system.assertEquals(0, [SELECT count() FROM Account],
            'The database should be unchanged');
    }
}
2
  • 1
    close as duplicate? Jun 7, 2019 at 14:25
  • 2
    Still trying to decide. I think for now I'll just post that as a comment and let the community vote.
    – Adrian Larson
    Jun 7, 2019 at 14:26

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