jamesward / salesforce-webhook-creator

MIT License
171 stars 71 forks source link

System.CalloutException #18

Open Mycleung opened 7 years ago

Mycleung commented 7 years ago

First of all - great work with this project. It's been amazing so far but it appears that I'm bumping into one of Salesforce's idiosyncrasies.

When I try to run my test in production (not in a sandbox), I get the following test failure in the generated WebhookTriggerTest:

System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out 
Stack Trace: Class.Webhook.callout: line 31, column 1

There's a couple of places that mention this error, here's one example: https://success.salesforce.com/issues_view?id=a1p30000000jbNMAAY

And my trigger code is here:

trigger BarkWebhookTrigger on Opportunity (after update,after insert) {

    String url = 'https://goodlord-bark.herokuapp.com/opportunity';

    String content = Webhook.jsonContent(Trigger.new, Trigger.old);

    Webhook.callout(url, content);

}

with everything else about the hook being default.

Please could I get some advice one what to do to work around this issue? I'm not sure how I'd modify the testcase to not perform an insert and callout...

Mycleung commented 7 years ago

Seems like I'm in a catch 22 situation here. The linked "fixed" issue in the previous comment says that the workaround is to retrieve an existing entry with an SOQL query, but the test environment doesn't have any cases of Opportunity which is the object I've added a hook to - so the only way to test my hook is to insert one during the test... right?

jamesward commented 7 years ago

Sorry for the delay! I've moved setting the mock to the Webhook class. I think that might fix this but I've been having a hard time reproducing this. Can you delete the generated trigger, test, and Webhook class, then recreate them via https://salesforce-webhook-creator.herokuapp.com/

Then re-run the tests and let me know what happens?

Mycleung commented 7 years ago

I'm afraid I'm not in a position where I can delete the triggers I've got set up. FTR my workaround to get through the testing phase was to add some testonly logic to the trigger (a massive hack, but oh well...)

    if (!Test.isRunningTest() && !body.isEmpty()) {
        Webhook.callout(url, bodyText);
    }
jamesward commented 7 years ago

Cool. Glad you found a workaround. In case you are curious, these are the changes to the Apex template that I think fixes this: https://github.com/jamesward/salesforce-webhook-creator/commit/32df70347abd790678eaf67137a5a82a1c4f38ad