-
Notifications
You must be signed in to change notification settings - Fork 9.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
core(tsc): add type checking to sentry usage (#5993)
- Loading branch information
1 parent
942cc02
commit 6656521
Showing
16 changed files
with
80 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,6 @@ | |
*/ | ||
'use strict'; | ||
|
||
// @ts-ignore | ||
const isEqual = require('lodash.isequal'); | ||
|
||
/** | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,94 +3,105 @@ | |
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. | ||
*/ | ||
// @ts-nocheck | ||
'use strict'; | ||
|
||
const log = require('lighthouse-logger'); | ||
|
||
// eslint-disable-next-line max-len | ||
/** @typedef {import('raven').CaptureOptions} CaptureOptions */ | ||
/** @typedef {import('raven').ConstructorOptions} ConstructorOptions */ | ||
|
||
const SENTRY_URL = 'https://a6bb0da87ee048cc9ae2a345fc09ab2e:[email protected]/174697'; | ||
|
||
const noop = () => Promise.resolve(); | ||
const sentryApi = { | ||
captureMessage: noop, | ||
captureException: noop, | ||
captureBreadcrumb: noop, | ||
mergeContext: noop, | ||
getContext: noop, | ||
}; | ||
// Per-run chance of capturing errors (if enabled). | ||
const SAMPLE_RATE = 0.01; | ||
|
||
/** @type {Array<{pattern: RegExp, rate: number}>} */ | ||
const SAMPLED_ERRORS = [ | ||
// Error code based sampling | ||
{pattern: /DOCUMENT_REQUEST$/, rate: 0.1}, | ||
{pattern: /(IDLE_PERIOD|FMP_TOO_LATE)/, rate: 0.1}, | ||
{pattern: /^NO_.*/, rate: 0.1}, | ||
// Message based sampling | ||
{pattern: /Could not load stylesheet/, rate: 0.01}, | ||
{pattern: /Failed to decode/, rate: 0.1}, | ||
{pattern: /All image optimizations failed/, rate: 0.1}, | ||
{pattern: /No.*resource with given/, rate: 0.01}, | ||
{pattern: /No.*node with given id/, rate: 0.01}, | ||
// Error code based sampling. Delete if still unused after 2019-01-01. | ||
// e.g.: {pattern: /No.*node with given id/, rate: 0.01}, | ||
]; | ||
|
||
const noop = () => {}; | ||
|
||
/** | ||
* We'll create a delegate for sentry so that environments without error reporting enabled will use | ||
* A delegate for sentry so that environments without error reporting enabled will use | ||
* noop functions and environments with error reporting will call the actual Sentry methods. | ||
*/ | ||
const sentryDelegate = Object.assign({}, sentryApi); | ||
sentryDelegate.init = function init(opts) { | ||
const sentryDelegate = { | ||
init, | ||
/** @type {(message: string, options?: CaptureOptions) => void} */ | ||
captureMessage: noop, | ||
/** @type {(breadcrumb: any) => void} */ | ||
captureBreadcrumb: noop, | ||
/** @type {() => any} */ | ||
getContext: noop, | ||
/** @type {(error: Error, options?: CaptureOptions) => Promise<void>} */ | ||
captureException: async () => {}, | ||
}; | ||
|
||
/** | ||
* When called, replaces noops with actual Sentry implementation. | ||
* @param {{url: string, flags: LH.CliFlags, environmentData: ConstructorOptions}} opts | ||
*/ | ||
function init(opts) { | ||
// If error reporting is disabled, leave the functions as a noop | ||
if (!opts.flags.enableErrorReporting) { | ||
// If error reporting is disabled, leave the functions as a noop | ||
return; | ||
} | ||
|
||
const environmentData = opts.environmentData || {}; | ||
const sentryConfig = Object.assign({}, environmentData, {captureUnhandledRejections: true}); | ||
// If not selected for samping, leave the functions as a noop. | ||
if (SAMPLE_RATE <= Math.random()) { | ||
return; | ||
} | ||
|
||
try { | ||
const Sentry = require('raven'); | ||
const sentryConfig = Object.assign({}, opts.environmentData, | ||
{captureUnhandledRejections: true}); | ||
Sentry.config(SENTRY_URL, sentryConfig).install(); | ||
Object.keys(sentryApi).forEach(functionName => { | ||
// Have each delegate function call the corresponding sentry function by default | ||
sentryDelegate[functionName] = (...args) => Sentry[functionName](...args); | ||
}); | ||
|
||
// Special case captureException to return a Promise so we don't process.exit too early | ||
sentryDelegate.captureException = (err, opts) => { | ||
opts = opts || {}; | ||
// Have each delegate function call the corresponding sentry function by default | ||
sentryDelegate.captureMessage = (...args) => Sentry.captureMessage(...args); | ||
sentryDelegate.captureBreadcrumb = (...args) => Sentry.captureBreadcrumb(...args); | ||
sentryDelegate.getContext = () => Sentry.getContext(); | ||
|
||
const empty = Promise.resolve(); | ||
// Special case captureException to return a Promise so we don't process.exit too early | ||
sentryDelegate.captureException = async (err, opts = {}) => { | ||
// Ignore if there wasn't an error | ||
if (!err) return empty; | ||
if (!err) return; | ||
|
||
// Ignore expected errors | ||
if (err.expected) return empty; | ||
// Sample known errors that occur at a high frequency | ||
// @ts-ignore Non-standard property added to flag error as not needing capturing. | ||
if (err.expected) return; | ||
|
||
// Sample known errors that occur at a high frequency. | ||
const sampledErrorMatch = SAMPLED_ERRORS.find(sample => sample.pattern.test(err.message)); | ||
if (sampledErrorMatch && sampledErrorMatch.rate <= Math.random()) return empty; | ||
if (sampledErrorMatch && sampledErrorMatch.rate <= Math.random()) return; | ||
|
||
// Protocol errors all share same stack trace, so add more to fingerprint | ||
// @ts-ignore - properties added to protocol method LHErrors. | ||
if (err.protocolMethod) { | ||
// @ts-ignore - properties added to protocol method LHErrors. | ||
opts.fingerprint = ['{{ default }}', err.protocolMethod, err.protocolError]; | ||
} | ||
|
||
return new Promise(resolve => { | ||
Sentry.captureException(err, opts, () => resolve()); | ||
}); | ||
}; | ||
|
||
const context = Object.assign({ | ||
url: opts.url, | ||
deviceEmulation: !opts.flags.disableDeviceEmulation, | ||
throttlingMethod: opts.flags.throttlingMethod, | ||
}, opts.flags.throttling); | ||
Sentry.mergeContext({extra: Object.assign({}, opts.environmentData.extra, context)}); | ||
} catch (e) { | ||
log.warn( | ||
'sentry', | ||
'Could not load raven library, errors will not be reported.' | ||
); | ||
} | ||
|
||
const context = Object.assign({ | ||
url: opts.url, | ||
deviceEmulation: !opts.flags.disableDeviceEmulation, | ||
throttlingMethod: opts.flags.throttlingMethod, | ||
}, opts.flags.throttling); | ||
|
||
sentryDelegate.mergeContext({extra: Object.assign({}, environmentData.extra, context)}); | ||
return context; | ||
}; | ||
} | ||
|
||
module.exports = sentryDelegate; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters