Determine if an SObject has an error
I 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..
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
}