From 9c12fd6c107990f066348e1923e12677f9038b61 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Tue, 14 Dec 2021 21:44:29 -0500 Subject: [PATCH] ref(browser): Extract private methods from breadcrumbs --- .../browser/src/integrations/breadcrumbs.ts | 290 +++++++++--------- 1 file changed, 143 insertions(+), 147 deletions(-) diff --git a/packages/browser/src/integrations/breadcrumbs.ts b/packages/browser/src/integrations/breadcrumbs.ts index 49a52ac5a7bf..5dc7cc8fb7c7 100644 --- a/packages/browser/src/integrations/breadcrumbs.ts +++ b/packages/browser/src/integrations/breadcrumbs.ts @@ -85,84 +85,47 @@ export class Breadcrumbs implements Integration { public setupOnce(): void { if (this._options.console) { addInstrumentationHandler({ - callback: (...args) => { - this._consoleBreadcrumb(...args); - }, + callback: _consoleBreadcrumb, type: 'console', }); } if (this._options.dom) { addInstrumentationHandler({ - callback: (...args) => { - this._domBreadcrumb(...args); - }, + callback: _domBreadcrumb(this._options.dom), type: 'dom', }); } if (this._options.xhr) { addInstrumentationHandler({ - callback: (...args) => { - this._xhrBreadcrumb(...args); - }, + callback: _xhrBreadcrumb, type: 'xhr', }); } if (this._options.fetch) { addInstrumentationHandler({ - callback: (...args) => { - this._fetchBreadcrumb(...args); - }, + callback: _fetchBreadcrumb, type: 'fetch', }); } if (this._options.history) { addInstrumentationHandler({ - callback: (...args) => { - this._historyBreadcrumb(...args); - }, + callback: _historyBreadcrumb, type: 'history', }); } } +} - /** - * Creates breadcrumbs from console API calls - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - private _consoleBreadcrumb(handlerData: { [key: string]: any }): void { - const breadcrumb = { - category: 'console', - data: { - arguments: handlerData.args, - logger: 'console', - }, - level: Severity.fromString(handlerData.level), - message: safeJoin(handlerData.args, ' '), - }; - - if (handlerData.level === 'assert') { - if (handlerData.args[0] === false) { - breadcrumb.message = `Assertion failed: ${safeJoin(handlerData.args.slice(1), ' ') || 'console.assert'}`; - breadcrumb.data.arguments = handlerData.args.slice(1); - } else { - // Don't capture a breadcrumb for passed assertions - return; - } - } - - getCurrentHub().addBreadcrumb(breadcrumb, { - input: handlerData.args, - level: handlerData.level, - }); - } - - /** - * Creates breadcrumbs from DOM API calls - */ +/** + * A HOC that creaes a function that creates breadcrumbs from DOM API calls. + * This is a HOC so that we get access to dom options in the closure. + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function _domBreadcrumb(dom: BreadcrumbsOptions['dom']): (handlerData: { [key: string]: any }) => void { // eslint-disable-next-line @typescript-eslint/no-explicit-any - private _domBreadcrumb(handlerData: { [key: string]: any }): void { + function _innerDomBreadcrumb(handlerData: { [key: string]: any }): void { let target; - let keyAttrs = typeof this._options.dom === 'object' ? this._options.dom.serializeAttribute : undefined; + let keyAttrs = typeof dom === 'object' ? dom.serializeAttribute : undefined; if (typeof keyAttrs === 'string') { keyAttrs = [keyAttrs]; @@ -194,117 +157,150 @@ export class Breadcrumbs implements Integration { ); } - /** - * Creates breadcrumbs from XHR API calls - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - private _xhrBreadcrumb(handlerData: { [key: string]: any }): void { - if (handlerData.endTimestamp) { - // We only capture complete, non-sentry requests - if (handlerData.xhr.__sentry_own_request__) { - return; - } - - const { method, url, status_code, body } = handlerData.xhr.__sentry_xhr__ || {}; + return _innerDomBreadcrumb; +} - getCurrentHub().addBreadcrumb( - { - category: 'xhr', - data: { - method, - url, - status_code, - }, - type: 'http', - }, - { - xhr: handlerData.xhr, - input: body, - }, - ); +/** + * Creates breadcrumbs from console API calls + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function _consoleBreadcrumb(handlerData: { [key: string]: any }): void { + const breadcrumb = { + category: 'console', + data: { + arguments: handlerData.args, + logger: 'console', + }, + level: Severity.fromString(handlerData.level), + message: safeJoin(handlerData.args, ' '), + }; + if (handlerData.level === 'assert') { + if (handlerData.args[0] === false) { + breadcrumb.message = `Assertion failed: ${safeJoin(handlerData.args.slice(1), ' ') || 'console.assert'}`; + breadcrumb.data.arguments = handlerData.args.slice(1); + } else { + // Don't capture a breadcrumb for passed assertions return; } } - /** - * Creates breadcrumbs from fetch API calls - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - private _fetchBreadcrumb(handlerData: { [key: string]: any }): void { - // We only capture complete fetch requests - if (!handlerData.endTimestamp) { - return; - } + getCurrentHub().addBreadcrumb(breadcrumb, { + input: handlerData.args, + level: handlerData.level, + }); +} - if (handlerData.fetchData.url.match(/sentry_key/) && handlerData.fetchData.method === 'POST') { - // We will not create breadcrumbs for fetch requests that contain `sentry_key` (internal sentry requests) +/** + * Creates breadcrumbs from XHR API calls + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function _xhrBreadcrumb(handlerData: { [key: string]: any }): void { + if (handlerData.endTimestamp) { + // We only capture complete, non-sentry requests + if (handlerData.xhr.__sentry_own_request__) { return; } - if (handlerData.error) { - getCurrentHub().addBreadcrumb( - { - category: 'fetch', - data: handlerData.fetchData, - level: Severity.Error, - type: 'http', - }, - { - data: handlerData.error, - input: handlerData.args, - }, - ); - } else { - getCurrentHub().addBreadcrumb( - { - category: 'fetch', - data: { - ...handlerData.fetchData, - status_code: handlerData.response.status, - }, - type: 'http', - }, - { - input: handlerData.args, - response: handlerData.response, + const { method, url, status_code, body } = handlerData.xhr.__sentry_xhr__ || {}; + + getCurrentHub().addBreadcrumb( + { + category: 'xhr', + data: { + method, + url, + status_code, }, - ); - } - } + type: 'http', + }, + { + xhr: handlerData.xhr, + input: body, + }, + ); - /** - * Creates breadcrumbs from history API calls - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - private _historyBreadcrumb(handlerData: { [key: string]: any }): void { - const global = getGlobalObject(); - let from = handlerData.from; - let to = handlerData.to; - const parsedLoc = parseUrl(global.location.href); - let parsedFrom = parseUrl(from); - const parsedTo = parseUrl(to); + return; + } +} - // Initial pushState doesn't provide `from` information - if (!parsedFrom.path) { - parsedFrom = parsedLoc; - } +/** + * Creates breadcrumbs from fetch API calls + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function _fetchBreadcrumb(handlerData: { [key: string]: any }): void { + // We only capture complete fetch requests + if (!handlerData.endTimestamp) { + return; + } - // Use only the path component of the URL if the URL matches the current - // document (almost all the time when using pushState) - if (parsedLoc.protocol === parsedTo.protocol && parsedLoc.host === parsedTo.host) { - to = parsedTo.relative; - } - if (parsedLoc.protocol === parsedFrom.protocol && parsedLoc.host === parsedFrom.host) { - from = parsedFrom.relative; - } + if (handlerData.fetchData.url.match(/sentry_key/) && handlerData.fetchData.method === 'POST') { + // We will not create breadcrumbs for fetch requests that contain `sentry_key` (internal sentry requests) + return; + } - getCurrentHub().addBreadcrumb({ - category: 'navigation', - data: { - from, - to, + if (handlerData.error) { + getCurrentHub().addBreadcrumb( + { + category: 'fetch', + data: handlerData.fetchData, + level: Severity.Error, + type: 'http', + }, + { + data: handlerData.error, + input: handlerData.args, }, - }); + ); + } else { + getCurrentHub().addBreadcrumb( + { + category: 'fetch', + data: { + ...handlerData.fetchData, + status_code: handlerData.response.status, + }, + type: 'http', + }, + { + input: handlerData.args, + response: handlerData.response, + }, + ); } } + +/** + * Creates breadcrumbs from history API calls + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function _historyBreadcrumb(handlerData: { [key: string]: any }): void { + const global = getGlobalObject(); + let from = handlerData.from; + let to = handlerData.to; + const parsedLoc = parseUrl(global.location.href); + let parsedFrom = parseUrl(from); + const parsedTo = parseUrl(to); + + // Initial pushState doesn't provide `from` information + if (!parsedFrom.path) { + parsedFrom = parsedLoc; + } + + // Use only the path component of the URL if the URL matches the current + // document (almost all the time when using pushState) + if (parsedLoc.protocol === parsedTo.protocol && parsedLoc.host === parsedTo.host) { + to = parsedTo.relative; + } + if (parsedLoc.protocol === parsedFrom.protocol && parsedLoc.host === parsedFrom.host) { + from = parsedFrom.relative; + } + + getCurrentHub().addBreadcrumb({ + category: 'navigation', + data: { + from, + to, + }, + }); +}