[WebService] Bugsnag API 使用筆記
使用版本 @
7.0.0
- JavaScript Integration Guide @ Bugsnag doc
- React integration guide @ Bugsnag doc
- Configuration options @ BugSnag doc
- Upgrading @ BugSnag Github
安裝(搭配 React)
$ npm install --save @bugsnag/js @bugsnag/plugin-react
載入:
// ES module-style import
import Bugsnag from '@bugsnag/js';
import BugsnagPluginReact from '@bugsnag/plugin-react';
使用:
Bugsnag.start({
apiKey: 'YOUR_API_KEY',
plugins: [new BugsnagPluginReact(React)],
otherOptions: value,
});
套用到 React:
const ErrorBoundary = Bugsnag.getPlugin('react');
回報錯誤訊息(notify)
// Bugsnag.notify(err, onError, cb)
import Bugsnag from '@bugsnag/js';
Bugsnag.notify(new Error('Something broke!'));
// 使用 onError function
Bugsnag.notify(new Error('Bad, but not fatal'), (event) => {
// return false 就不會送出
if (event.getUser().id === '1') return false;
event.severity = 'info';
event.context = 'component-space-246';
event.setUser('1', 'bugs.nag@bugsnag.com', 'B. Nag');
event.addMetadata('hyperflopz', { count: 23 });
});
// 使用 callback
Bugsnag.notify(new Error('uh oh'), null, function (err, event) {
if (err) {
console.log('Failed to send report because of:\n' + err.stack);
} else {
console.log('Successfully sent report "' + event.errors[0].errorMessage + '"');
}
});
客製化錯誤訊息(metadata)
Customizing error reports @ Bugsnag Docs
Bugsnag.addMetadata(section, key, value)
Bugsnag.addMetadata(section, { [key]: value, …})
在 v7 之後,原本的 beforeSend
改名為 onError
,裡面接收的參數從 report
改名為 event
;原先的 updateMetaData
也改為 addMetadata
。詳細的說明可以參考升級 指南(Upgrading):
⚠️ 留意原本是用大駝峰的
metaData
修正為metadata
。
export const bugsnagClient = bugsnag({
apiKey: BUGSNAG_API_KEY,
onError: (event) => {
// 透過 addMetadata 更新資料到 metadata 中,如此不會覆蓋原有的 metadata
// 添加 user 資料
event.setUser(id, email, name);
event.addMetadata('user', state?.personalInfo);
// 添加 device 資料
event.addMetadata('device', state?.deviceInfo);
// 添加其他客製化資料
event.addMetadata('project', state?.app);
event.addMetadata('networkQuality', state?.webRTC?.networkQuality);
},
});
客製化 breadcrumb
Customizing breadcrumbs @ Bugsnag Docs
Bugsnag.leaveBreadcrumb('Preference updated', metadata, 'state');
透過 onBreadcrumb
:
Bugsnag.start({
apiKey: BUGSNAG_API_KEY,
onError: (event) => {
/*...*/
},
onBreadcrumb: (breadcrumb) => {
/* breadcrumb 物件 { message, metadata, timestamp, type } */
if (breadcrumb.type === 'navigation' && breadcrumb.metadata.to === '/home') {
return false;
}
breadcrumb.metadata.to = stripQueryString(breadcrumb.metadata.to);
breadcrumb.metadata.path = state?.path;
},
});
⚠️ 如果在 log 會留下 breadcrumb 的話,在 onBreadcrumb 中使用
console.log
可能會導致無窮迴圈。
客製化 logger
Configuration options > logger @ bugsnag
const logger = {
debug: (message) => console.log('[bugsnag] debug: ', message),
info: (message) => console.info('[bugsnag] info: ', message),
warn: (message) => console.warn('[bugsnag] warn: ', message),
error: (message) => console.error('[bugsnag] error: ', message),
};
Bugsnag.start({
apiKey: BUGSNAG_API_KEY,
...(process.env.NODE_ENV === 'development' && { logger }),
});
上傳 SourceMap
uploading source maps @ BugSnag > Build & deploy integrations > Node.js/npm scripts
問題解決
在 Chrome Extension 或第三方服務使用 Bugsnag
如果有使用 Bugsnag 這類第三方的錯誤通知程式,需要留意使用的方式略有不同:
參考:How can I get error reports from browser extensions? @ bugsnag docs
For v.7x.x
:
// v7.x.x
export const bugsnagClient = Bugsnag.createClient({
//...
onError: (event) => {
event.errors.map((error) => {
return error.stacktrace.map(function (frame) {
frame.file = frame.file.replace(
/chrome-extension:/g,
'chrome_extension:'
);
return frame;
});
});
}
})
module.export bugsnagClient;
另外,由於在 Chrome Extension 中有可能需要同時在 content-script 和 background 中使用 bugsnagClient,因此需使用 createClient
並 export 這個 client,並可以在 onError
的時候透過不同的 context
來區別:
export const bugsnagClient = Bugsnag.createClient({
apiKey: BUGSNAG_API_KEY,
plugins: [new BugsnagPluginReact(React)],
appVersion,
releaseStage: process.env.NODE_ENV || 'development',
// FIXME:
// enabledReleaseStages: ['production'],
...(process.env.NODE_ENV === 'development' && { logger }),
onError: (event) => {
event.errors.map((error) => {
// ...
});
// 使用 context 來區分是在 background 或 front (content-script, iframe) 被呼叫
if (event.context.includes('background')) {
event.context = 'background';
} else if (event.context.includes('index')) {
event.context = 'front-side';
}
},
});
⚠️ 即使 background 和 front-side(content-script, iframe)是
import
同一支檔案的 bugsnagClient,但因為是在不同的環境下,所以載到的 bugsnagClient 會是獨立的,也就是在不同的 execution context。
For v6.x.x
:
// v6.x.x
bugsnag({
beforeSend: function (report) {
report.stacktrace = report.stacktrace.map(function (frame) {
frame.file = frame.file.replace(/chrome-extension:/g, 'chrome_extension:');
return frame;
});
},
});