Skip to content

Commit 652eaac

Browse files
authored
chore(ember): Show warning when using invalid config (#6032)
When defining Sentry config in `ENV['@sentry/ember'].sentry`, this goes through @embroider/macros under the hood. This relies on config being serializable, which means that e.g. you cannot use regex in the config. To make this easier to pin down (as the error message can be a bit cryptic), this now validates the passed config (based on embroider-build/embroider#1083) and shows a helpful warning message. Note that this also moved this around a bit, leading to config being written only once on build, which should be a bit faster.
1 parent b0908d0 commit 652eaac

File tree

1 file changed

+53
-4
lines changed

1 file changed

+53
-4
lines changed

packages/ember/index.js

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,22 @@ module.exports = {
2727
},
2828
},
2929

30-
config(_, appConfig) {
31-
const addonConfig = appConfig['@sentry/ember'];
32-
this.options['@embroider/macros'].setOwnConfig.sentryConfig = { ...addonConfig };
33-
return this._super(...arguments);
30+
included() {
31+
const app = this._findHost();
32+
const config = app.project.config(app.env);
33+
const addonConfig = config['@sentry/ember'] || {};
34+
35+
if (!isSerializable(addonConfig)) {
36+
console.warn(
37+
`Warning: You passed a non-serializable config to \`ENV['@sentry/ember'].sentry\`.
38+
Non-serializable config (e.g. RegExp, ...) can only be passed directly to \`Sentry.init()\`, which is usually defined in app/app.js.
39+
The reason for this is that @embroider/macros, which is used under the hood to handle environment config, requires serializable configuration.`,
40+
);
41+
}
42+
43+
this.options['@embroider/macros'].setOwnConfig.sentryConfig = addonConfig;
44+
45+
this._super.included.apply(this, arguments);
3446
},
3547

3648
contentFor(type, config) {
@@ -50,3 +62,40 @@ module.exports = {
5062

5163
injectedScriptHashes: [initialLoadHeadSnippetHash, initialLoadBodySnippetHash],
5264
};
65+
66+
function isSerializable(obj) {
67+
if (isScalar(obj)) {
68+
return true;
69+
}
70+
71+
if (Array.isArray(obj)) {
72+
return !obj.some(arrayItem => !isSerializable(arrayItem));
73+
}
74+
75+
if (isPlainObject(obj)) {
76+
for (let property in obj) {
77+
let value = obj[property];
78+
if (!isSerializable(value)) {
79+
return false;
80+
}
81+
}
82+
83+
return true;
84+
}
85+
86+
return false;
87+
}
88+
89+
function isScalar(val) {
90+
return (
91+
typeof val === 'undefined' ||
92+
typeof val === 'string' ||
93+
typeof val === 'boolean' ||
94+
typeof val === 'number' ||
95+
val === null
96+
);
97+
}
98+
99+
function isPlainObject(obj) {
100+
return typeof obj === 'object' && obj.constructor === Object && obj.toString() === '[object Object]';
101+
}

0 commit comments

Comments
 (0)