6

Scenario : Before inserting a record I will check another System(REST call) and then decide(control) to insert or update in Trigger context.

I have Trigger which does REST call inside future method.

Problem : The DML executes before future returns me any value.

I do not want to run any Scheduled jobs or do REST call outside Trigger context as I need this check happening in Trigger context.

Is there any alternative to get the future method return result and then continue the Trigger execution ?

4
  • 2
    why don't you make DML inside future? You can pass the object list as JSON string. Commented Oct 11, 2016 at 5:59
  • What happens if the future call takes 10 minutes? half an hour? 5 hours? Do you want the trigger frozen for that period of time?
    – Nick C
    Commented Oct 11, 2016 at 6:14
  • @NickCook In that case how do we Insert/Update data based on External Systems decision ? Insert may be I can delete inside Future if I have Ids of the records I am dealing with. But If it was update I do not know to what state of record I need to revert back or roll back.
    – Soberano
    Commented Oct 11, 2016 at 6:18
  • @Soberano Tushar's suggestion above seems the best way.
    – Nick C
    Commented Oct 11, 2016 at 6:34

1 Answer 1

11

SF will just not let you do a synchronous callout from a trigger. Which makes sense because the external system might be slow, and SF has to lock the record being updated while your trigger runs. If they allowed you to callout from a trigger, there could end up being lots of locks in the system, all waiting for callouts to complete and this would kill the database performance.

My preferred method is to use picklist values on the record to record the status of the callout i.e.

  • Add two new fields to your record: Callout Status: {'Pending', 'Complete', 'Error'}, Callout Result: whatever type it needs to be
  • Have your existing trigger set Callout Status to Pending and start the @future method
  • When the future method completes, have it set Callout Status to 'Complete' and store the result in Callout Result
  • Write a second trigger which fires on Callout Status becoming 'Complete' and uses Callout Result to perform your decision-making process

I prefer this to just firing off an @future method without the Status field because it means that you can detect problems with your @future. e.g. if the external system returns an unexpected result and your @future method dies with an exception, you will be able to see (with a report) that the corresponding record has got stuck with Status='Pending'. Without that, your @future methods can just silently fail, and you wouldn't know that there was a problem. IMO, that safeguard is pretty much essential due to SF having uncatchable exceptions which prevent you from writing bombproof error handlers.

You must log in to answer this question.

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