diff --git a/Libraries/Core/polyfillPromise.js b/Libraries/Core/polyfillPromise.js index b15ccc2b301d25..6551745bf52c5d 100644 --- a/Libraries/Core/polyfillPromise.js +++ b/Libraries/Core/polyfillPromise.js @@ -19,4 +19,20 @@ const {polyfillGlobal} = require('../Utilities/PolyfillFunctions'); * If you don't need these polyfills, don't use InitializeCore; just directly * require the modules you need from InitializeCore for setup. */ -polyfillGlobal('Promise', () => require('../Promise')); + +// If global.Promise is provided by Hermes, we are confident that it can provide +// all the methods needed by React Native, so we can directly use it. +if (global?.HermesInternal?.hasPromise?.()) { + const HermesPromise = global.Promise; + + if (__DEV__) { + if (typeof HermesPromise !== 'function') { + console.error('HermesPromise does not exist'); + } + global.HermesInternal.enablePromiseRejectionTracker( + require('../promiseRejectionTrackingOptions').default, + ); + } +} else { + polyfillGlobal('Promise', () => require('../Promise')); +} diff --git a/Libraries/Promise.js b/Libraries/Promise.js index 836c2978a73065..fc06e9f35db06d 100644 --- a/Libraries/Promise.js +++ b/Libraries/Promise.js @@ -16,42 +16,9 @@ require('promise/setimmediate/done'); require('promise/setimmediate/finally'); if (__DEV__) { - require('promise/setimmediate/rejection-tracking').enable({ - allRejections: true, - onUnhandled: (id, rejection = {}) => { - let message: string; - let stack: ?string; - - const stringValue = Object.prototype.toString.call(rejection); - if (stringValue === '[object Error]') { - message = Error.prototype.toString.call(rejection); - const error: Error = (rejection: $FlowFixMe); - stack = error.stack; - } else { - try { - message = require('pretty-format')(rejection); - } catch { - message = - typeof rejection === 'string' - ? rejection - : JSON.stringify((rejection: $FlowFixMe)); - } - } - - const warning = - `Possible Unhandled Promise Rejection (id: ${id}):\n` + - `${message ?? ''}\n` + - (stack == null ? '' : stack); - console.warn(warning); - }, - onHandled: id => { - const warning = - `Promise Rejection Handled (id: ${id})\n` + - 'This means you can ignore any previous messages of the form ' + - `"Possible Unhandled Promise Rejection (id: ${id}):"`; - console.warn(warning); - }, - }); + require('promise/setimmediate/rejection-tracking').enable( + require('./promiseRejectionTrackingOptions').default, + ); } module.exports = Promise; diff --git a/Libraries/promiseRejectionTrackingOptions.js b/Libraries/promiseRejectionTrackingOptions.js new file mode 100644 index 00000000000000..7b30a9c66bb4bd --- /dev/null +++ b/Libraries/promiseRejectionTrackingOptions.js @@ -0,0 +1,54 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + * @flow strict + */ + +'use strict'; + +import typeof {enable} from 'promise/setimmediate/rejection-tracking'; + +type ExtractOptionsType =

((options?: ?P) => void) => P; + +let rejectionTrackingOptions: $Call = { + allRejections: true, + onUnhandled: (id, rejection = {}) => { + let message: string; + let stack: ?string; + + const stringValue = Object.prototype.toString.call(rejection); + if (stringValue === '[object Error]') { + message = Error.prototype.toString.call(rejection); + const error: Error = (rejection: $FlowFixMe); + stack = error.stack; + } else { + try { + message = require('pretty-format')(rejection); + } catch { + message = + typeof rejection === 'string' + ? rejection + : JSON.stringify((rejection: $FlowFixMe)); + } + } + + const warning = + `Possible Unhandled Promise Rejection (id: ${id}):\n` + + `${message ?? ''}\n` + + (stack == null ? '' : stack); + console.warn(warning); + }, + onHandled: id => { + const warning = + `Promise Rejection Handled (id: ${id})\n` + + 'This means you can ignore any previous messages of the form ' + + `"Possible Unhandled Promise Rejection (id: ${id}):"`; + console.warn(warning); + }, +}; + +export default rejectionTrackingOptions;