diff --git a/packages/ember/index.js b/packages/ember/index.js index 130d5f33ed5f..01b742c44e0c 100644 --- a/packages/ember/index.js +++ b/packages/ember/index.js @@ -27,10 +27,20 @@ module.exports = { }, }, - config(_, appConfig) { - const addonConfig = appConfig['@sentry/ember']; - this.options['@embroider/macros'].setOwnConfig.sentryConfig = { ...addonConfig }; - return this._super(...arguments); + included() { + const app = this._findHost(); + const config = app.project.config(app.env); + const addonConfig = config['@sentry/ember'] || {}; + + if (!isSerializable(addonConfig)) { + console.warn( + "Warning: You passed a non-serializable config to `ENV['@sentry/ember'].sentry`. Non-serializable config (e.g. RegExp, ...) can only be passed directly to `Sentry.init()`.", + ); + } + + this.options['@embroider/macros'].setOwnConfig.sentryConfig = addonConfig; + + this._super.included.apply(this, arguments); }, contentFor(type, config) { @@ -50,3 +60,40 @@ module.exports = { injectedScriptHashes: [initialLoadHeadSnippetHash, initialLoadBodySnippetHash], }; + +function isSerializable(obj) { + if (isScalar(obj)) { + return true; + } + + if (Array.isArray(obj)) { + return !obj.some(arrayItem => !isSerializable(arrayItem)); + } + + if (isPlainObject(obj)) { + for (let property in obj) { + let value = obj[property]; + if (!isSerializable(value)) { + return false; + } + } + + return true; + } + + return false; +} + +function isScalar(val) { + return ( + typeof val === 'undefined' || + typeof val === 'string' || + typeof val === 'boolean' || + typeof val === 'number' || + val === null + ); +} + +function isPlainObject(obj) { + return typeof obj === 'object' && obj.constructor === Object && obj.toString() === '[object Object]'; +}