15

Since years I'm using Metadata and Tooling Apex classes to connect with those APIs (based on Andrew Fawcetts work here https://github.com/afawcett/apex-toolingapi). Today I'm encountering a very strange issue in form of an package upload error which I can not understand. The issue seems totally wired and without any logical connection...

In hours of work, I was finally able to drill it down to just 3 easy things, 100% reproducible within minutes:

  1. ToolingAPI.cls (http://www.elastify.org/ToolingAPI.cls) - set to API v36.0
  2. ToolingAPITest.cls (http://www.elastify.org/ToolingAPITest.cls) - v36.0, too.
  3. One empty Lightning Component (details below)

Due to size limits I could not save the post with all the code, so I put the classes on my homepage. These are older versions from around 2013, but still work flawlessly.

With just the two classes:

  • you can run tests: they succeed with no problems.
  • create a new unmanaged package
  • add both classes to the package
  • upload the package: no problems, tests succeed again.

Now let's add a blank component:

  • create an new empty lightning component (only <aura:component ></aura:component>) with developer console.
  • add that to the package
  • and upload it: all good, it still works, no problem!

Finally we add a controller:

  • create an empty(!) JS controller inside the lightning component (consisting just of ({})).
  • try to upload the package again ==> now the Apex tests are failing with

System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out

Class.ToolingAPI.submitRestCall: line 2355, column 1, Class.ToolingAPI.submitRestCall: line 2317, column 1, Class.ToolingAPI.submitRestCall: line 2309, column 1, Class.ToolingAPI.query: line 132, column 1, Class.ToolingAPITest.testQueryApexClassMember: line 67, column 1

  • running the test with Dev Console or at setup: no error!
  • deleting just the empty controller, I can upload the package again, the error disappeared!
  • API version of the compo seems irrelevant. I've tried v36.0 and v41.0, no differece.

I can't figure what can be wrong here. At this point, I can only think of a very strange salesforce error.

It must be related to callouts in conjunction with the existence of a lightning componets JS controller. Crazy! I have another class wrapping the metadata-api based on https://github.com/financialforcedev/apex-mdapi: with that the same is happening.

Update 2017-10-16 - existing package-members immune

I have older packages which contains lots of lightning compos with controllers already. Those I still can upload together with ToolingAPI with no issues - only new compos added are creating the error. However if you save the existing component they will start to produce that error, too. Luckily I got one disposable component to try this... So now I can't make any changes to all of my vital lightning components, or I will loose the ability to upload the package. Not nice!

Update (2017-10-18) - possibly related with test.setMock()

I think that it is related to the mockup tests. It looks like the Test.setMock() is not working (e.g. line 56 of ToolingAPITest.cls) and during the tests, not the mockup, but the real callout is invoked. And as a result it's failing.

As a workaround I'm trying to hack some test.isRunningTest() into the code and trying to return null instead something "meaningful". Also I have to wipe all System.assert...() to make this fly. But this hack is total crap, plus messing up the code, plus it will degrade my coverage. Bottom-line: this workaround is not OK, but I have to upload this package with a lot of time-pressure - no matter what.

For a real solution I'm out of ideas. Totally.

Unfortunately I have no premier support and Salesforce will shut my ticket down in the support immediately.

enter image description here

  • 4
    That is very odd, but you are right - I tried your classes with a test package I keep handy and get the same result. Remove the JS, and it uploads. Let me raise with Premier Support and see what they have to say... – BritishBoyinDC Oct 13 '17 at 18:47
  • @BritishBoyinDC thank you so much, I highly appreciate your help on this! – Uwe Heim Oct 14 '17 at 10:18
  • Quick update - Support has been able to re-create it in their Winter 18 Sandboxes, so it is looking like a bug right now...will let you know if they create a KI – BritishBoyinDC Oct 17 '17 at 22:41
  • 1
    I just hit this issue in another packaging org. But when I wrapped the code in the test that invokes the callout between a test.StartTest/StopTest, I was then able to upload the package...so might be worth trying that. Support is supposed to get back to me tomorrow with an update. – BritishBoyinDC Oct 23 '17 at 18:02
  • 1
    @BritishBoyinDC thank you so much for all your feedback!! test.startTest() and test.stopTest() are doing the magic and it WORKS! And the best is, that the coverage stays exactly as it was before without that start/stop. So why don't you answer this question with that workaround? And provide the final feedback from the support into that answer, too. I will accept this as solution. – Uwe Heim Oct 24 '17 at 11:30
7

I was able to replicate this issue in two packages, so have raised it with support, and they are currently researching it (they were able to re-create it)

One thing I noticed as a workaround - I had many classes with mock callouts, both Web Service and HTTP. But only some failed - and they both did NOT make use of Start/Stop Test.

So even though they worked fine in regular test runs, once I updated my tests to invoke the code that invokes the callouts like below, I could then upload the package.

Test.StartTest() 
    //Invoke code that makes callout
Test.Stop Test()
2

For reference and tracking, here is the known issue:

https://success.salesforce.com/issues_view?id=a1p3A000000EO8L

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.