function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
kevoharakevohara 

Before Trigger DML with addError()

I am creating a validation "before" trigger that I am using to validate fields before inserting a record.  What I want to do is to create a log record every time a validation fails.  Ideally, I would want to:

 

1) Display the validation error to the user in typical fashion using the addError() method.

 

2) Insert a Log record into my custom object called "Log__c" to record the incident.

 

I can't find it in the docs, but the usage of the addError() method seems to disallow any DML...even to my custom object.  Whats weird is that I am not getting an exception on my insert statement.  In fact, the debug logs show that the insert was executed successfully, however, no record is actually created in my Log object.  My guess is that there is a rollback occurring when addError() is used.

 

I thought that executing my DML in a asynchronous method would circumvent this so I moved the log insertion into an @future method.  This didn't help either.

 

Is there a way I can perform this insert when my before trigger calls an addError() method on a field?

Best Answer chosen by Admin (Salesforce Developers) 
bob_buzzardbob_buzzard

This is a pretty common catch 22 situation.  The problem is that if you want to stop the record from being created via trigger validation, you have to add an error to the record.  This causes the entire transaction to be rolled back, which means that you can't store any other information, aside from entries in the system log.

 

One way to get around this is to have an @future method that is fired from the trigger and let that do the validation and potentially delete the record.  The downside is that the user thinks their save has worked correctly and shortly afterwards the record disappears.  

All Answers

bob_buzzardbob_buzzard

This is a pretty common catch 22 situation.  The problem is that if you want to stop the record from being created via trigger validation, you have to add an error to the record.  This causes the entire transaction to be rolled back, which means that you can't store any other information, aside from entries in the system log.

 

One way to get around this is to have an @future method that is fired from the trigger and let that do the validation and potentially delete the record.  The downside is that the user thinks their save has worked correctly and shortly afterwards the record disappears.  

This was selected as the best answer
MatthewBotos_MatthewBotos_

As Bob pointed out, you'd have to execute any DML a completely separate context.

 

Another possible approach would be to email the log message to an InboundMessageHandler which could then insert it.

bob_buzzardbob_buzzard

Unfortunately that wouldn't work either - if you roll the transaction back, any emails that were due to be sent are also rolled back.

kevoharakevohara

Yeah, I have given up here.  This does present a problem because I have been asked several times to build validation triggers that prevent the insert of certain data, but also log the occurrence.  

Kirill_YunussovKirill_Yunussov
Vote on an idea to implement this: https://success.salesforce.com/ideaView?id=08730000000l0UcAAI