2016-12-07 02:36:45 +05:30
|
|
|
import Raven from 'raven-js';
|
|
|
|
|
2017-03-29 11:16:20 +05:30
|
|
|
import abbreviate from './abbreviate';
|
|
|
|
|
2019-12-09 13:17:24 +05:30
|
|
|
const isTest = process.env.NODE_ENV === 'test';
|
|
|
|
const isProduction = process.env.NODE_ENV === 'production';
|
2016-12-07 02:36:45 +05:30
|
|
|
|
2018-05-02 23:18:50 +05:30
|
|
|
class Logger {
|
2020-01-14 17:51:38 +05:30
|
|
|
init({ sentryDSN }: { sentryDSN: string }) {
|
|
|
|
if (sentryDSN) {
|
|
|
|
Raven.config(sentryDSN, {
|
2019-11-27 14:33:32 +05:30
|
|
|
logger: 'accounts-js-app',
|
|
|
|
level: 'info',
|
2019-12-09 13:17:24 +05:30
|
|
|
environment: process.env.APP_ENV,
|
|
|
|
release: process.env.__VERSION__,
|
2019-11-27 14:33:32 +05:30
|
|
|
shouldSendCallback: () => !isTest,
|
|
|
|
dataCallback: data => {
|
|
|
|
if (!data.level) {
|
|
|
|
// log unhandled errors as info
|
|
|
|
data.level = 'info';
|
|
|
|
}
|
|
|
|
|
|
|
|
return data;
|
|
|
|
},
|
|
|
|
whitelistUrls: isProduction ? [/ely\.by/] : [],
|
|
|
|
}).install();
|
|
|
|
|
|
|
|
window.addEventListener('unhandledrejection', event => {
|
|
|
|
const error = event.reason || {};
|
|
|
|
|
|
|
|
let message = error.message || error;
|
|
|
|
|
|
|
|
if (typeof message === 'string') {
|
|
|
|
message = `: ${message}`;
|
|
|
|
} else {
|
|
|
|
message = '';
|
2016-12-07 02:36:45 +05:30
|
|
|
}
|
|
|
|
|
2019-11-27 14:33:32 +05:30
|
|
|
this.info(`Unhandled rejection${message}`, {
|
|
|
|
error,
|
|
|
|
event,
|
2016-12-07 02:36:45 +05:30
|
|
|
});
|
2019-11-27 14:33:32 +05:30
|
|
|
});
|
2016-12-07 02:36:45 +05:30
|
|
|
}
|
2019-11-27 14:33:32 +05:30
|
|
|
}
|
2016-12-07 02:36:45 +05:30
|
|
|
|
2019-12-07 16:58:52 +05:30
|
|
|
setUser(user: {
|
|
|
|
username: string | null;
|
|
|
|
email: string | null;
|
|
|
|
id: number | null;
|
|
|
|
}) {
|
2019-11-27 14:33:32 +05:30
|
|
|
Raven.setUserContext({
|
|
|
|
username: user.username,
|
|
|
|
email: user.email,
|
|
|
|
id: user.id,
|
|
|
|
});
|
|
|
|
}
|
2018-05-05 14:31:25 +05:30
|
|
|
|
2019-12-07 16:58:52 +05:30
|
|
|
unexpected(message: string | Error, previous: any) {
|
2019-11-27 14:33:32 +05:30
|
|
|
// TODO: check whether previous was already handled. Cover with tests
|
|
|
|
this.error(message, {
|
|
|
|
error: previous,
|
|
|
|
});
|
|
|
|
}
|
2017-03-02 11:28:33 +05:30
|
|
|
|
2019-12-07 16:58:52 +05:30
|
|
|
error(message: string | Error, context?: { [key: string]: any }) {
|
2019-11-27 14:33:32 +05:30
|
|
|
log('error', message, context);
|
|
|
|
}
|
2017-03-29 11:16:20 +05:30
|
|
|
|
2019-12-07 16:58:52 +05:30
|
|
|
info(message: string | Error, context?: { [key: string]: any }) {
|
2019-11-27 14:33:32 +05:30
|
|
|
log('info', message, context);
|
|
|
|
}
|
2018-05-02 23:52:13 +05:30
|
|
|
|
2019-12-07 16:58:52 +05:30
|
|
|
warn(message: string | Error, context?: { [key: string]: any }) {
|
2019-11-27 14:33:32 +05:30
|
|
|
log('warning', message, context);
|
|
|
|
}
|
|
|
|
|
|
|
|
getLastEventId(): string | void {
|
|
|
|
return Raven.lastEventId();
|
|
|
|
}
|
2018-05-02 23:18:50 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
function log(
|
2019-11-27 14:33:32 +05:30
|
|
|
level: 'error' | 'warning' | 'info' | 'debug',
|
|
|
|
message: string | Error,
|
2019-12-07 16:58:52 +05:30
|
|
|
context?: { [key: string]: any },
|
2018-05-02 23:18:50 +05:30
|
|
|
) {
|
2019-11-27 14:33:32 +05:30
|
|
|
const method: 'error' | 'warn' | 'info' | 'debug' =
|
|
|
|
level === 'warning' ? 'warn' : level;
|
|
|
|
|
|
|
|
if (isTest) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof context !== 'object') {
|
|
|
|
// it would better to always have an object here
|
|
|
|
context = {
|
|
|
|
message: context,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
prepareContext(context).then(context => {
|
|
|
|
console[method](message, context); // eslint-disable-line
|
|
|
|
|
|
|
|
Raven.captureException(message, {
|
|
|
|
level,
|
|
|
|
extra: context,
|
|
|
|
...(typeof message === 'string' ? { fingerprint: [message] } : {}),
|
2018-05-02 23:18:50 +05:30
|
|
|
});
|
2019-11-27 14:33:32 +05:30
|
|
|
});
|
2018-05-02 23:18:50 +05:30
|
|
|
}
|
2016-12-07 02:36:45 +05:30
|
|
|
|
2017-04-15 12:29:11 +05:30
|
|
|
/**
|
|
|
|
* prepare data for JSON.stringify
|
|
|
|
*
|
|
|
|
* @param {object} context
|
|
|
|
*
|
2019-11-27 14:33:32 +05:30
|
|
|
* @returns {Promise}
|
2017-04-15 12:29:11 +05:30
|
|
|
*/
|
2019-12-07 16:58:52 +05:30
|
|
|
function prepareContext(context: { [key: string]: any }) {
|
2019-11-27 14:33:32 +05:30
|
|
|
if (context instanceof Response) {
|
|
|
|
// TODO: rewrite abbreviate to use promises and recursively find Response
|
|
|
|
return context
|
|
|
|
.json()
|
|
|
|
.catch(() => context.text())
|
|
|
|
.then(body =>
|
|
|
|
abbreviate({
|
|
|
|
type: context.type,
|
|
|
|
url: context.url,
|
|
|
|
status: context.status,
|
|
|
|
statusText: context.statusText,
|
|
|
|
body,
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
} else if (context.originalResponse instanceof Response) {
|
|
|
|
return prepareContext(context.originalResponse).then(originalResponse =>
|
|
|
|
abbreviate({
|
|
|
|
...context,
|
|
|
|
originalResponse,
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Promise.resolve(abbreviate(context));
|
2017-04-15 12:29:11 +05:30
|
|
|
}
|
|
|
|
|
2018-05-02 23:18:50 +05:30
|
|
|
export default new Logger();
|