Does addError() work outside of triggers?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}
I moved a method that sets addError()
from a trigger into a Helper class. As I started writing test code for it it seems like the addError()
is not actually preventing DML operations for the records that get modified in the helper class.
The information from the SF SObject class page states:
Marks a trigger record with a custom error message and prevents any DML operation from occurring.
Does this mean that addError()
will not work outside of a trigger class?
EDIT
Adding some sample code.
public class MyHelperClass() {
public static void someMethod(Opportunity opp) {
opp.My_Field__c.addError('Some error');
insert opp;
}
}
And sample test for it without any asserts:
@IsTest
private class MyHelperClass_Test() {
@IsTest
static void someTest() {
Opportunity opp = new Opportunity();
opp.Name = 'Some Name';
opp.StageName = 'Prospect';
opp.CloseDate = Date.today().addDays(30);
MyHelperClass.someMethod(opp);
}
}
The above inserts the opportunity and does not trigger an exception. Am I doing something wrong?
apex trigger adderror
add a comment |
I moved a method that sets addError()
from a trigger into a Helper class. As I started writing test code for it it seems like the addError()
is not actually preventing DML operations for the records that get modified in the helper class.
The information from the SF SObject class page states:
Marks a trigger record with a custom error message and prevents any DML operation from occurring.
Does this mean that addError()
will not work outside of a trigger class?
EDIT
Adding some sample code.
public class MyHelperClass() {
public static void someMethod(Opportunity opp) {
opp.My_Field__c.addError('Some error');
insert opp;
}
}
And sample test for it without any asserts:
@IsTest
private class MyHelperClass_Test() {
@IsTest
static void someTest() {
Opportunity opp = new Opportunity();
opp.Name = 'Some Name';
opp.StageName = 'Prospect';
opp.CloseDate = Date.today().addDays(30);
MyHelperClass.someMethod(opp);
}
}
The above inserts the opportunity and does not trigger an exception. Am I doing something wrong?
apex trigger adderror
addError works in Visualforce controllers, Visualforce extensions, and anywhere within a Trigger context. It might be you simply made a mistake somewhere; it won't block DML operations on records not involved in Trigger.new or Trigger.old (for delete events only). We probably need to see the actual code to help you.
– sfdcfox
May 14 at 16:09
@sfdcfox I added sample code. Let me know if this makes more sense?
– Arthlete
May 14 at 16:15
add a comment |
I moved a method that sets addError()
from a trigger into a Helper class. As I started writing test code for it it seems like the addError()
is not actually preventing DML operations for the records that get modified in the helper class.
The information from the SF SObject class page states:
Marks a trigger record with a custom error message and prevents any DML operation from occurring.
Does this mean that addError()
will not work outside of a trigger class?
EDIT
Adding some sample code.
public class MyHelperClass() {
public static void someMethod(Opportunity opp) {
opp.My_Field__c.addError('Some error');
insert opp;
}
}
And sample test for it without any asserts:
@IsTest
private class MyHelperClass_Test() {
@IsTest
static void someTest() {
Opportunity opp = new Opportunity();
opp.Name = 'Some Name';
opp.StageName = 'Prospect';
opp.CloseDate = Date.today().addDays(30);
MyHelperClass.someMethod(opp);
}
}
The above inserts the opportunity and does not trigger an exception. Am I doing something wrong?
apex trigger adderror
I moved a method that sets addError()
from a trigger into a Helper class. As I started writing test code for it it seems like the addError()
is not actually preventing DML operations for the records that get modified in the helper class.
The information from the SF SObject class page states:
Marks a trigger record with a custom error message and prevents any DML operation from occurring.
Does this mean that addError()
will not work outside of a trigger class?
EDIT
Adding some sample code.
public class MyHelperClass() {
public static void someMethod(Opportunity opp) {
opp.My_Field__c.addError('Some error');
insert opp;
}
}
And sample test for it without any asserts:
@IsTest
private class MyHelperClass_Test() {
@IsTest
static void someTest() {
Opportunity opp = new Opportunity();
opp.Name = 'Some Name';
opp.StageName = 'Prospect';
opp.CloseDate = Date.today().addDays(30);
MyHelperClass.someMethod(opp);
}
}
The above inserts the opportunity and does not trigger an exception. Am I doing something wrong?
apex trigger adderror
apex trigger adderror
edited May 14 at 16:15
Arthlete
asked May 14 at 15:58
ArthleteArthlete
1,1541221
1,1541221
addError works in Visualforce controllers, Visualforce extensions, and anywhere within a Trigger context. It might be you simply made a mistake somewhere; it won't block DML operations on records not involved in Trigger.new or Trigger.old (for delete events only). We probably need to see the actual code to help you.
– sfdcfox
May 14 at 16:09
@sfdcfox I added sample code. Let me know if this makes more sense?
– Arthlete
May 14 at 16:15
add a comment |
addError works in Visualforce controllers, Visualforce extensions, and anywhere within a Trigger context. It might be you simply made a mistake somewhere; it won't block DML operations on records not involved in Trigger.new or Trigger.old (for delete events only). We probably need to see the actual code to help you.
– sfdcfox
May 14 at 16:09
@sfdcfox I added sample code. Let me know if this makes more sense?
– Arthlete
May 14 at 16:15
addError works in Visualforce controllers, Visualforce extensions, and anywhere within a Trigger context. It might be you simply made a mistake somewhere; it won't block DML operations on records not involved in Trigger.new or Trigger.old (for delete events only). We probably need to see the actual code to help you.
– sfdcfox
May 14 at 16:09
addError works in Visualforce controllers, Visualforce extensions, and anywhere within a Trigger context. It might be you simply made a mistake somewhere; it won't block DML operations on records not involved in Trigger.new or Trigger.old (for delete events only). We probably need to see the actual code to help you.
– sfdcfox
May 14 at 16:09
@sfdcfox I added sample code. Let me know if this makes more sense?
– Arthlete
May 14 at 16:15
@sfdcfox I added sample code. Let me know if this makes more sense?
– Arthlete
May 14 at 16:15
add a comment |
2 Answers
2
active
oldest
votes
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');
}
}
That's very similar to my use case. How would you cover the line of code forrecord.addError('You cannot insert this record');
if you were to write test code for thePreventDml
class alone? Is there a way to assert that theaddError
was set alone?
– Arthlete
May 14 at 16:33
1
@Arthlete Unlike other service methods, validation can only be effectively tested by running the trigger. There are hacks like checkingApexPages.hasMessages()
, but they may not work in future releases, nor in all contexts even in the current release.
– Adrian Larson♦
May 14 at 16:44
Thank you, I will remember this!
– Arthlete
May 14 at 16:46
add a comment |
addError won't block future DML operations, only those already in progress. You can use addError in any class, but it won't have any effect on future operations. As an example of what would work:
trigger myFieldBlock on Opportunity {
myFieldBlock.validate(Trigger.new);
}
public class myFieldBlock {
public static void validate(Opportunity records) {
records[0].My_Field__c.addError('Some error');
}
}
You can also use addError to display errors on a Visualforce page:
public class VFController {
public Account record { get; set; }
public VFController() {
record = new Account();
}
public void showError() {
record.Name.addError('Some error');
}
}
<apex:page controller="VFController">
<apex:form>
<apex:inputField value="{!record.Name}" />
<apex:commandButton value="Show Error" action="{!showError}" />
</apex:form>
</apex:page>
i did not get this. We add addError in trigger to prevent DML operations from occurring. Your first snippet should prevent any DML operation on the record as its been called from Trigger Context. However in VF snippet even if there is any DML after we add error, it will execute.
– Anshul Agrawal
May 15 at 13:15
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "459"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f262376%2fdoes-adderror-work-outside-of-triggers%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
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');
}
}
That's very similar to my use case. How would you cover the line of code forrecord.addError('You cannot insert this record');
if you were to write test code for thePreventDml
class alone? Is there a way to assert that theaddError
was set alone?
– Arthlete
May 14 at 16:33
1
@Arthlete Unlike other service methods, validation can only be effectively tested by running the trigger. There are hacks like checkingApexPages.hasMessages()
, but they may not work in future releases, nor in all contexts even in the current release.
– Adrian Larson♦
May 14 at 16:44
Thank you, I will remember this!
– Arthlete
May 14 at 16:46
add a comment |
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');
}
}
That's very similar to my use case. How would you cover the line of code forrecord.addError('You cannot insert this record');
if you were to write test code for thePreventDml
class alone? Is there a way to assert that theaddError
was set alone?
– Arthlete
May 14 at 16:33
1
@Arthlete Unlike other service methods, validation can only be effectively tested by running the trigger. There are hacks like checkingApexPages.hasMessages()
, but they may not work in future releases, nor in all contexts even in the current release.
– Adrian Larson♦
May 14 at 16:44
Thank you, I will remember this!
– Arthlete
May 14 at 16:46
add a comment |
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');
}
}
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');
}
}
edited May 14 at 16:42
answered May 14 at 16:23
Adrian Larson♦Adrian Larson
113k19127267
113k19127267
That's very similar to my use case. How would you cover the line of code forrecord.addError('You cannot insert this record');
if you were to write test code for thePreventDml
class alone? Is there a way to assert that theaddError
was set alone?
– Arthlete
May 14 at 16:33
1
@Arthlete Unlike other service methods, validation can only be effectively tested by running the trigger. There are hacks like checkingApexPages.hasMessages()
, but they may not work in future releases, nor in all contexts even in the current release.
– Adrian Larson♦
May 14 at 16:44
Thank you, I will remember this!
– Arthlete
May 14 at 16:46
add a comment |
That's very similar to my use case. How would you cover the line of code forrecord.addError('You cannot insert this record');
if you were to write test code for thePreventDml
class alone? Is there a way to assert that theaddError
was set alone?
– Arthlete
May 14 at 16:33
1
@Arthlete Unlike other service methods, validation can only be effectively tested by running the trigger. There are hacks like checkingApexPages.hasMessages()
, but they may not work in future releases, nor in all contexts even in the current release.
– Adrian Larson♦
May 14 at 16:44
Thank you, I will remember this!
– Arthlete
May 14 at 16:46
That's very similar to my use case. How would you cover the line of code for
record.addError('You cannot insert this record');
if you were to write test code for the PreventDml
class alone? Is there a way to assert that the addError
was set alone?– Arthlete
May 14 at 16:33
That's very similar to my use case. How would you cover the line of code for
record.addError('You cannot insert this record');
if you were to write test code for the PreventDml
class alone? Is there a way to assert that the addError
was set alone?– Arthlete
May 14 at 16:33
1
1
@Arthlete Unlike other service methods, validation can only be effectively tested by running the trigger. There are hacks like checking
ApexPages.hasMessages()
, but they may not work in future releases, nor in all contexts even in the current release.– Adrian Larson♦
May 14 at 16:44
@Arthlete Unlike other service methods, validation can only be effectively tested by running the trigger. There are hacks like checking
ApexPages.hasMessages()
, but they may not work in future releases, nor in all contexts even in the current release.– Adrian Larson♦
May 14 at 16:44
Thank you, I will remember this!
– Arthlete
May 14 at 16:46
Thank you, I will remember this!
– Arthlete
May 14 at 16:46
add a comment |
addError won't block future DML operations, only those already in progress. You can use addError in any class, but it won't have any effect on future operations. As an example of what would work:
trigger myFieldBlock on Opportunity {
myFieldBlock.validate(Trigger.new);
}
public class myFieldBlock {
public static void validate(Opportunity records) {
records[0].My_Field__c.addError('Some error');
}
}
You can also use addError to display errors on a Visualforce page:
public class VFController {
public Account record { get; set; }
public VFController() {
record = new Account();
}
public void showError() {
record.Name.addError('Some error');
}
}
<apex:page controller="VFController">
<apex:form>
<apex:inputField value="{!record.Name}" />
<apex:commandButton value="Show Error" action="{!showError}" />
</apex:form>
</apex:page>
i did not get this. We add addError in trigger to prevent DML operations from occurring. Your first snippet should prevent any DML operation on the record as its been called from Trigger Context. However in VF snippet even if there is any DML after we add error, it will execute.
– Anshul Agrawal
May 15 at 13:15
add a comment |
addError won't block future DML operations, only those already in progress. You can use addError in any class, but it won't have any effect on future operations. As an example of what would work:
trigger myFieldBlock on Opportunity {
myFieldBlock.validate(Trigger.new);
}
public class myFieldBlock {
public static void validate(Opportunity records) {
records[0].My_Field__c.addError('Some error');
}
}
You can also use addError to display errors on a Visualforce page:
public class VFController {
public Account record { get; set; }
public VFController() {
record = new Account();
}
public void showError() {
record.Name.addError('Some error');
}
}
<apex:page controller="VFController">
<apex:form>
<apex:inputField value="{!record.Name}" />
<apex:commandButton value="Show Error" action="{!showError}" />
</apex:form>
</apex:page>
i did not get this. We add addError in trigger to prevent DML operations from occurring. Your first snippet should prevent any DML operation on the record as its been called from Trigger Context. However in VF snippet even if there is any DML after we add error, it will execute.
– Anshul Agrawal
May 15 at 13:15
add a comment |
addError won't block future DML operations, only those already in progress. You can use addError in any class, but it won't have any effect on future operations. As an example of what would work:
trigger myFieldBlock on Opportunity {
myFieldBlock.validate(Trigger.new);
}
public class myFieldBlock {
public static void validate(Opportunity records) {
records[0].My_Field__c.addError('Some error');
}
}
You can also use addError to display errors on a Visualforce page:
public class VFController {
public Account record { get; set; }
public VFController() {
record = new Account();
}
public void showError() {
record.Name.addError('Some error');
}
}
<apex:page controller="VFController">
<apex:form>
<apex:inputField value="{!record.Name}" />
<apex:commandButton value="Show Error" action="{!showError}" />
</apex:form>
</apex:page>
addError won't block future DML operations, only those already in progress. You can use addError in any class, but it won't have any effect on future operations. As an example of what would work:
trigger myFieldBlock on Opportunity {
myFieldBlock.validate(Trigger.new);
}
public class myFieldBlock {
public static void validate(Opportunity records) {
records[0].My_Field__c.addError('Some error');
}
}
You can also use addError to display errors on a Visualforce page:
public class VFController {
public Account record { get; set; }
public VFController() {
record = new Account();
}
public void showError() {
record.Name.addError('Some error');
}
}
<apex:page controller="VFController">
<apex:form>
<apex:inputField value="{!record.Name}" />
<apex:commandButton value="Show Error" action="{!showError}" />
</apex:form>
</apex:page>
answered May 14 at 16:24
sfdcfoxsfdcfox
273k14221472
273k14221472
i did not get this. We add addError in trigger to prevent DML operations from occurring. Your first snippet should prevent any DML operation on the record as its been called from Trigger Context. However in VF snippet even if there is any DML after we add error, it will execute.
– Anshul Agrawal
May 15 at 13:15
add a comment |
i did not get this. We add addError in trigger to prevent DML operations from occurring. Your first snippet should prevent any DML operation on the record as its been called from Trigger Context. However in VF snippet even if there is any DML after we add error, it will execute.
– Anshul Agrawal
May 15 at 13:15
i did not get this. We add addError in trigger to prevent DML operations from occurring. Your first snippet should prevent any DML operation on the record as its been called from Trigger Context. However in VF snippet even if there is any DML after we add error, it will execute.
– Anshul Agrawal
May 15 at 13:15
i did not get this. We add addError in trigger to prevent DML operations from occurring. Your first snippet should prevent any DML operation on the record as its been called from Trigger Context. However in VF snippet even if there is any DML after we add error, it will execute.
– Anshul Agrawal
May 15 at 13:15
add a comment |
Thanks for contributing an answer to Salesforce Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f262376%2fdoes-adderror-work-outside-of-triggers%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
addError works in Visualforce controllers, Visualforce extensions, and anywhere within a Trigger context. It might be you simply made a mistake somewhere; it won't block DML operations on records not involved in Trigger.new or Trigger.old (for delete events only). We probably need to see the actual code to help you.
– sfdcfox
May 14 at 16:09
@sfdcfox I added sample code. Let me know if this makes more sense?
– Arthlete
May 14 at 16:15