PJCHENder 未整理筆記

[WebService] Bugsnag API 使用筆記

2020-04-01

[API] Bugsnag API 使用筆記

使用版本 @ 7.0.0

安裝(搭配 React)

1
$ npm install --save @bugsnag/js @bugsnag/plugin-react

載入:

1
2
3
// ES module-style import
import Bugsnag from '@bugsnag/js'
import BugsnagPluginReact from '@bugsnag/plugin-react'

使用:

1
2
3
4
5
Bugsnag.start({
apiKey: 'YOUR_API_KEY',
plugins: [new BugsnagPluginReact(React)],
otherOptions: value
})

套用到 React:

1
const ErrorBoundary = Bugsnag.getPlugin('react')

回報錯誤訊息(notify)

Reporting handled errors

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
// 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

1
2
Bugsnag.addMetadata(section, key, value)
Bugsnag.addMetadata(section, { [key]: value, …})

在 v7 之後,原本的 beforeSend 改名為 onError,裡面接收的參數從 report 改名為 event;原先的 updateMetaData 也改為 addMetadata。詳細的說明可以參考升級指南(Upgrading)

⚠️ 留意原本是用大駝峰的 metaData 修正為 metadata

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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

1
Bugsnag.leaveBreadcrumb('Preference updated', metadata, 'state')

透過 onBreadcrumb

1
2
3
4
5
6
7
8
9
10
11
12
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

1
2
3
4
5
6
7
8
9
10
11
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 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 來區別:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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

1
2
3
4
5
6
7
8
9
// 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
})
}
})
Tags: API

掃描二維條碼,分享此文章