Is there a way to calculate if an SObject in a trigger context has had an error added to it (either with addError
or through a validation rule)?
I have some trigger processes I don't want to run if we don't end up inserting/updating this sobject.
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It only takes a minute to sign up.
Sign up to join this communityI don't think there is a direct method for determining if an sObject has errors on it. There might be a method to tell, but I would rely on the triggers order of operations here. Any DML operations will fail if there's an added error, so by running those processes in an after
trigger context will ensure that the record survived the initial process without getting an error added.
Looks like ApexPages.HasMessages()
will return true in a trigger context! Not only that, but the severity parameters will return accurate information. ApexPages.GetMessages()
will even go as far as to return the actual messages added, despite there being no page associated with the trigger.
Execute Anon Snippet:
insert new Account(Name = 'Test');
Trigger (Set up to fail & print message info)
trigger TestTrigger on Account (before insert) {
for (Account a:trigger.new) {
a.Name.AddError('Forced Failure');
}
System.debug(ApexPages.hasMessages()); // true
System.debug(ApexPages.hasMessages(ApexPages.Severity.ERROR)); // true
for (ApexPages.Message message:ApexPages.getMessages()) {
System.debug(message.getComponentLabel()); // Account Name
System.debug(message.getDetail()); // Forced Failure
System.debug(message.getSeverity()); // Error
System.debug(message.getSummary()); // Forced Failure
}
}
All the methods of ApexPages.Message
return useful information, but since the Message
class was designed to work with standard visualforce pages, which have only a single record related to that page, they don't seem to store the id of the record with the message, which is a problem for determining which records have failed.
Theres a constructor to create a Message
with an Id, but it looks like its meant for a visualforce element id, not a record id, and theres still no easy way to get that value..
if (!ApexPages.HasMessages(ApexPages.Severity.ERROR)) { //.. }
to control entering expensive calls. .
Jan 24, 2018 at 19:21
ApexPages.AddMessage(new ApexPages.Message(Severity, 'Error Info', 'Details', 'RecordId'));
instead of using sObject.addError
, but since you can't do sObject.Field.AddError(new ApexPages.Message)
its kind of pointless - you might as well write your own error handling framework instead of trying to force messages to work outside of their intended context. Even if there were ids available through messages, not all trigger records will have an id, so it only kind of helps.
Jan 24, 2018 at 19:39
ApexPages.hasMessages can only be called from a Visualforce page
As of Winter '21, there is a method called hasErrors()
on SObjects (ref). The way to solve this problem now is to call:
Account acct = new Account();
// doSomething to acct;
if (!acct.hasErrors()) {
// do something
}