Split.io: Conflict replacing Promise.then

I am trying to include a SDK in our Meteor 2.2 app: Split.io’s Node SDK . We are using this SDK in other Node apps. However, when it runs in Meteor, it crashes while attempting to replace the then property of a Promise… which is apparently ok in other environments, but not in Meteor (I think that’s on purpose based on the latest version of meteor/promise). Here is the error:

W20210714-18:02:14.087(-3)? (STDERR) (node:3220222) UnhandledPromiseRejectionWarning: TypeError: Cannot assign to read only property 'then' of object '#<Promise>'
W20210714-18:02:14.088(-3)? (STDERR)     at chain (/home/x/tmp/meteor-split/simple-todos/node_modules/@splitsoftware/splitio/lib/utils/promise/wrapper.js:42:21)

Does Meteor implement its own Promise object? Or otherwise, is there a way to prevent Meteor from replacing then by that read-only property? We are just looking into including this SDK, so any ideas for doing it are greatly welcome (including building meteor differently, installing splitio differently, etc).

For the record and if it helps: there is a very easy way to reproduce the same problem the splitio package generates, which is simply

'use strict';
(new Promise(function() {})).then = function() {};

From there we verified the same thing works in node in general, but not in Meteor. And it also works if we remove 'use strict' in the example; but that’s not something we can do from within the built SDK.

Just for the reference, here’s where Meteor’s own global Promise implementation is being created and made closed for modifications:

Apparently that core initialization code runs before any application code.

Based on the comments on the top of the module it becomes clear that Meteor heavily relies on their own Fiber compatible Promise implementation:

It’s vitally important that we wrap Fiber.yield and other yielding
methods before we call makeCompatible, because the meteor-promise
implementation captures Fiber.yield and keeps calling the captured
version, which ignores any wrapping that happens later.

I’m no Meteor core expert, but if I had to guess, tempering with Meteor’s own Promise would probably render the app dysfunctional.

1 Like