forked from getsentry/sentry-javascript
/
index.ts
122 lines (104 loc) · 3.97 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import * as Sentry from '@sentry/browser';
import { SDK_VERSION, BrowserOptions } from '@sentry/browser';
import { macroCondition, isDevelopingApp, getOwnConfig } from '@embroider/macros';
import { next } from '@ember/runloop';
import { assert, warn } from '@ember/debug';
import Ember from 'ember';
import { timestampWithMs } from '@sentry/utils';
import { GlobalConfig, OwnConfig } from './types';
import { getGlobalObject } from '@sentry/utils';
function _getSentryInitConfig() {
const _global = getGlobalObject<GlobalConfig>();
_global.__sentryEmberConfig = _global.__sentryEmberConfig ?? {};
return _global.__sentryEmberConfig;
}
export function InitSentryForEmber(_runtimeConfig?: BrowserOptions) {
const environmentConfig = getOwnConfig<OwnConfig>().sentryConfig;
assert('Missing configuration.', environmentConfig);
assert('Missing configuration for Sentry.', environmentConfig.sentry || _runtimeConfig);
if (!environmentConfig.sentry) {
// If environment config is not specified but the above assertion passes, use runtime config.
environmentConfig.sentry = { ..._runtimeConfig } as any;
}
// Merge runtime config into environment config, preferring runtime.
Object.assign(environmentConfig.sentry, _runtimeConfig || {});
const initConfig = Object.assign({}, environmentConfig.sentry);
initConfig._metadata = initConfig._metadata || {};
initConfig._metadata.sdk = {
name: 'sentry.javascript.ember',
packages: [
{
name: 'npm:@sentry/ember',
version: SDK_VERSION,
},
],
version: SDK_VERSION,
};
// Persist Sentry init options so they are identical when performance initializers call init again.
const sentryInitConfig = _getSentryInitConfig();
Object.assign(sentryInitConfig, initConfig);
Sentry.init(initConfig);
if (macroCondition(isDevelopingApp())) {
if (environmentConfig.ignoreEmberOnErrorWarning) {
return;
}
next(null, function () {
warn(
'Ember.onerror found. Using Ember.onerror can hide some errors (such as flushed runloop errors) from Sentry. Use Sentry.captureException to capture errors within Ember.onError or remove it to have errors caught by Sentry directly. This error can be silenced via addon configuration.',
!Ember.onerror,
{
id: '@sentry/ember.ember-onerror-detected',
},
);
});
}
}
export const getActiveTransaction = () => {
return Sentry.getCurrentHub()?.getScope()?.getTransaction();
};
export const instrumentRoutePerformance = (BaseRoute: any) => {
const instrumentFunction = async (op: string, description: string, fn: Function, args: any) => {
const startTimestamp = timestampWithMs();
const result = await fn(...args);
const currentTransaction = getActiveTransaction();
if (!currentTransaction) {
return result;
}
currentTransaction.startChild({ op, description, startTimestamp }).finish();
return result;
};
return {
[BaseRoute.name]: class extends BaseRoute {
beforeModel(...args: any[]) {
return instrumentFunction(
'ui.ember.route.before_model',
(<any>this).fullRouteName,
super.beforeModel.bind(this),
args,
);
}
async model(...args: any[]) {
return instrumentFunction('ui.ember.route.model', (<any>this).fullRouteName, super.model.bind(this), args);
}
async afterModel(...args: any[]) {
return instrumentFunction(
'ui.ember.route.after_model',
(<any>this).fullRouteName,
super.afterModel.bind(this),
args,
);
}
async setupController(...args: any[]) {
return instrumentFunction(
'ui.ember.route.setup_controller',
(<any>this).fullRouteName,
super.setupController.bind(this),
args,
);
}
},
}[BaseRoute.name];
};
export * from '@sentry/browser';
// init is now the preferred way to call initialization for this addon.
export const init = InitSentryForEmber;