Skip to content

ref: Rewrite to use optional chaining & add eslint rule #14966

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ sentryTest(
const errorEvent = events.find(event => event.message === 'console error');
const traceEvent = events.find(event => event.message === 'console trace');
const errorWithErrorEvent = events.find(
event => event.exception && event.exception.values?.[0].value === 'console error with error object',
event => event.exception?.values?.[0].value === 'console error with error object',
);
const traceWithErrorEvent = events.find(
event => event.exception && event.exception.values?.[0].value === 'console trace with error object',
event => event.exception?.values?.[0].value === 'console trace with error object',
);

expect(logEvent).toEqual(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ sentryTest('it captures console messages correctly', async ({ getLocalTestUrl, p
const errorEvent = events.find(event => event.message === 'console error');
const traceEvent = events.find(event => event.message === 'console trace');
const errorWithErrorEvent = events.find(
event => event.exception && event.exception.values?.[0].value === 'console error with error object',
event => event.exception?.values?.[0].value === 'console error with error object',
);
const traceWithErrorEvent = events.find(
event => event.exception && event.exception.values?.[0].value === 'console trace with error object',
event => event.exception?.values?.[0].value === 'console trace with error object',
);

expect(logEvent).toEqual(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ sentryTest('Flag evaluations in forked scopes are stored separately.', async ({
const url = await getLocalTestUrl({ testDir: __dirname, skipDsnRouteHandler: true });
await page.goto(url);

const forkedReqPromise = waitForErrorRequest(page, event => !!event.tags && event.tags.isForked === true);
const mainReqPromise = waitForErrorRequest(page, event => !!event.tags && event.tags.isForked === false);
const forkedReqPromise = waitForErrorRequest(page, event => !!event.tags?.isForked === true);
const mainReqPromise = waitForErrorRequest(page, event => !!event.tags?.isForked === false);

await page.evaluate(() => {
const Sentry = (window as any).Sentry;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ sentryTest('Flag evaluations in forked scopes are stored separately.', async ({
const url = await getLocalTestUrl({ testDir: __dirname, skipDsnRouteHandler: true });
await page.goto(url);

const forkedReqPromise = waitForErrorRequest(page, event => !!event.tags && event.tags.isForked === true);
const mainReqPromise = waitForErrorRequest(page, event => !!event.tags && event.tags.isForked === false);
const forkedReqPromise = waitForErrorRequest(page, event => !!event.tags?.isForked === true);
const mainReqPromise = waitForErrorRequest(page, event => !!event.tags?.isForked === false);

await page.evaluate(() => {
const Sentry = (window as any).Sentry;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ sentryTest('Flag evaluations in forked scopes are stored separately.', async ({
const url = await getLocalTestUrl({ testDir: __dirname, skipDsnRouteHandler: true });
await page.goto(url);

const forkedReqPromise = waitForErrorRequest(page, event => !!event.tags && event.tags.isForked === true);
const mainReqPromise = waitForErrorRequest(page, event => !!event.tags && event.tags.isForked === false);
const forkedReqPromise = waitForErrorRequest(page, event => !!event.tags?.isForked === true);
const mainReqPromise = waitForErrorRequest(page, event => !!event.tags?.isForked === false);

await page.evaluate(() => {
const Sentry = (window as any).Sentry;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const sentryCarrier = window?.__SENTRY__;
* Simulate an old pre v8 SDK obtaining the hub from the global sentry carrier
* and checking for the hub version.
*/
const res = sentryCarrier.acs && sentryCarrier.acs.getCurrentScope();
const res = sentryCarrier.acs?.getCurrentScope();

// Write back result into the document
document.getElementById('currentScope').innerText = res && 'scope';
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const sentryCarrier = window?.__SENTRY__;
* Simulate an old pre v8 SDK obtaining the hub from the global sentry carrier
* and checking for the hub version.
*/
const res = sentryCarrier.hub && sentryCarrier.hub.isOlderThan(7);
const res = sentryCarrier.hub?.isOlderThan(7);

// Write back result into the document
document.getElementById('olderThan').innerText = res;
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { getReplayEvent, shouldSkipReplayTest, waitForReplayRequest } from '../.

sentryTest('should capture replays offline', async ({ getLocalTestUrl, page }) => {
// makeBrowserOfflineTransport is not included in any CDN bundles
if (shouldSkipReplayTest() || (process.env.PW_BUNDLE && process.env.PW_BUNDLE.startsWith('bundle'))) {
if (shouldSkipReplayTest() || process.env.PW_BUNDLE?.startsWith('bundle')) {
sentryTest.skip();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ sentryTest(
async ({ getLocalTestUrl, page, forceFlushReplay }) => {
const bundle = process.env.PW_BUNDLE;

if (!bundle || !bundle.startsWith('bundle_') || bundle.includes('replay')) {
if (!bundle?.startsWith('bundle_') || bundle.includes('replay')) {
sentryTest.skip();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ sentryTest(
async ({ getLocalTestUrl, page, forceFlushReplay }) => {
const bundle = process.env.PW_BUNDLE;

if (!bundle || !bundle.startsWith('bundle_') || bundle.includes('replay')) {
if (!bundle?.startsWith('bundle_') || bundle.includes('replay')) {
sentryTest.skip();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function delay(ms: number) {

sentryTest('should queue and retry events when they fail to send', async ({ getLocalTestUrl, page }) => {
// makeBrowserOfflineTransport is not included in any CDN bundles
if (process.env.PW_BUNDLE && process.env.PW_BUNDLE.startsWith('bundle')) {
if (process.env.PW_BUNDLE?.startsWith('bundle')) {
sentryTest.skip();
}

Expand Down
2 changes: 1 addition & 1 deletion packages/angular/src/zone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ declare const Zone: any;
// Therefore, it's advisable to safely check whether the `run` function is
// available in the `<root>` context.
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
const isNgZoneEnabled = typeof Zone !== 'undefined' && Zone.root && Zone.root.run;
const isNgZoneEnabled = typeof Zone !== 'undefined' && Zone.root?.run;

/**
* The function that does the same job as `NgZone.runOutsideAngular`.
Expand Down
2 changes: 1 addition & 1 deletion packages/browser-utils/src/getNativeImplementation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export function getNativeImplementation<T extends keyof CacheableImplementations
sandbox.hidden = true;
document.head.appendChild(sandbox);
const contentWindow = sandbox.contentWindow;
if (contentWindow && contentWindow[name]) {
if (contentWindow?.[name]) {
impl = contentWindow[name] as CacheableImplementations[T];
}
document.head.removeChild(sandbox);
Expand Down
4 changes: 2 additions & 2 deletions packages/browser-utils/src/instrument/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export function instrumentDOM(): void {
const proto = globalObject[target]?.prototype;

// eslint-disable-next-line no-prototype-builtins
if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) {
if (!proto?.hasOwnProperty?.('addEventListener')) {
return;
}

Expand Down Expand Up @@ -169,7 +169,7 @@ function shouldSkipDOMEvent(eventType: string, target: SentryWrappedTarget | nul
return false;
}

if (!target || !target.tagName) {
if (!target?.tagName) {
return true;
}

Expand Down
4 changes: 2 additions & 2 deletions packages/browser-utils/src/metrics/browserMetrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export function startTrackingWebVitals({ recordClsStandaloneSpans }: StartTracki
fidCleanupCallback();
lcpCleanupCallback();
ttfbCleanupCallback();
clsCleanupCallback && clsCleanupCallback();
clsCleanupCallback?.();
};
}

Expand Down Expand Up @@ -300,7 +300,7 @@ interface AddPerformanceEntriesOptions {
/** Add performance related spans to a transaction */
export function addPerformanceEntries(span: Span, options: AddPerformanceEntriesOptions): void {
const performance = getBrowserPerformanceAPI();
if (!performance || !performance.getEntries || !browserPerformanceTimeOrigin) {
if (!performance?.getEntries || !browserPerformanceTimeOrigin) {
// Gatekeeper if performance API not available
return;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/browser-utils/src/metrics/cls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export function trackClsAsStandaloneSpan(): void {

const unsubscribeStartNavigation = client.on('startNavigationSpan', () => {
_collectClsOnce();
unsubscribeStartNavigation && unsubscribeStartNavigation();
unsubscribeStartNavigation?.();
});

const activeSpan = getActiveSpan();
Expand All @@ -93,7 +93,7 @@ function sendStandaloneClsSpan(clsValue: number, entry: LayoutShift | undefined,
const startTime = msToSec((browserPerformanceTimeOrigin || 0) + (entry?.startTime || 0));
const routeName = getCurrentScope().getScopeData().transactionName;

const name = entry ? htmlTreeAsString(entry.sources[0] && entry.sources[0].node) : 'Layout shift';
const name = entry ? htmlTreeAsString(entry.sources[0]?.node) : 'Layout shift';

const attributes: SpanAttributes = dropUndefinedKeys({
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.browser.cls',
Expand Down
2 changes: 1 addition & 1 deletion packages/browser-utils/src/metrics/instrument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ export function addPerformanceInstrumentationHandler(
function triggerHandlers(type: InstrumentHandlerType, data: unknown): void {
const typeHandlers = handlers[type];

if (!typeHandlers || !typeHandlers.length) {
if (!typeHandlers?.length) {
return;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/browser-utils/src/metrics/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export function startStandaloneWebVitalSpan(options: StandaloneWebVitalSpanOptio
// Web vital score calculation relies on the user agent to account for different
// browsers setting different thresholds for what is considered a good/meh/bad value.
// For example: Chrome vs. Chrome Mobile
'user_agent.original': WINDOW.navigator && WINDOW.navigator.userAgent,
'user_agent.original': WINDOW.navigator?.userAgent,

...passedAttributes,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ import { WINDOW } from '../../../types';
// sentry-specific change:
// add optional param to not check for responseStart (see comment below)
export const getNavigationEntry = (checkResponseStart = true): PerformanceNavigationTiming | void => {
const navigationEntry =
WINDOW.performance && WINDOW.performance.getEntriesByType && WINDOW.performance.getEntriesByType('navigation')[0];
const navigationEntry = WINDOW.performance?.getEntriesByType?.('navigation')[0];
// Check to ensure the `responseStart` property is present and valid.
// In some cases no value is reported by the browser (for
// privacy/security reasons), and in other cases (bugs) the value is
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ export const initMetric = <MetricName extends MetricType['name']>(name: MetricNa
let navigationType: MetricType['navigationType'] = 'navigate';

if (navEntry) {
if ((WINDOW.document && WINDOW.document.prerendering) || getActivationStart() > 0) {
if (WINDOW.document?.prerendering || getActivationStart() > 0) {
navigationType = 'prerender';
} else if (WINDOW.document && WINDOW.document.wasDiscarded) {
} else if (WINDOW.document?.wasDiscarded) {
navigationType = 'restore';
} else if (navEntry.type) {
navigationType = navEntry.type.replace(/_/g, '-') as MetricType['navigationType'];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export const processInteractionEntry = (entry: PerformanceEventTiming) => {
existingInteraction.latency = entry.duration;
} else if (
entry.duration === existingInteraction.latency &&
entry.startTime === (existingInteraction.entries[0] && existingInteraction.entries[0].startTime)
entry.startTime === existingInteraction.entries[0]?.startTime
) {
existingInteraction.entries.push(entry);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export interface OnHiddenCallback {
// simulate the page being hidden.
export const onHidden = (cb: OnHiddenCallback) => {
const onHiddenOrPageHide = (event: Event) => {
if (event.type === 'pagehide' || (WINDOW.document && WINDOW.document.visibilityState === 'hidden')) {
if (event.type === 'pagehide' || WINDOW.document?.visibilityState === 'hidden') {
cb(event);
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import { WINDOW } from '../../../types';

export const whenActivated = (callback: () => void) => {
if (WINDOW.document && WINDOW.document.prerendering) {
if (WINDOW.document?.prerendering) {
addEventListener('prerenderingchange', () => callback(), true);
} else {
callback();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const whenIdle = (cb: () => void): number => {
cb = runOnce(cb) as () => void;
// If the document is hidden, run the callback immediately, otherwise
// race an idle callback with the next `visibilitychange` event.
if (WINDOW.document && WINDOW.document.visibilityState === 'hidden') {
if (WINDOW.document?.visibilityState === 'hidden') {
cb();
} else {
handle = rIC(cb);
Expand Down
4 changes: 2 additions & 2 deletions packages/browser-utils/src/metrics/web-vitals/onTTFB.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ export const TTFBThresholds: MetricRatingThresholds = [800, 1800];
* @param callback
*/
const whenReady = (callback: () => void) => {
if (WINDOW.document && WINDOW.document.prerendering) {
if (WINDOW.document?.prerendering) {
whenActivated(() => whenReady(callback));
} else if (WINDOW.document && WINDOW.document.readyState !== 'complete') {
} else if (WINDOW.document?.readyState !== 'complete') {
addEventListener('load', () => whenReady(callback), true);
} else {
// Queue a task so the callback runs after `loadEventEnd`.
Expand Down
2 changes: 1 addition & 1 deletion packages/browser/src/integrations/breadcrumbs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ function _getHistoryBreadcrumbHandler(client: Client): (handlerData: HandlerData
const parsedTo = parseUrl(to);

// Initial pushState doesn't provide `from` information
if (!parsedFrom || !parsedFrom.path) {
if (!parsedFrom?.path) {
parsedFrom = parsedLoc;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/browser/src/integrations/browserapierrors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ function _wrapEventTarget(target: string): void {
const proto = globalObject[target]?.prototype;

// eslint-disable-next-line no-prototype-builtins
if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) {
if (!proto?.hasOwnProperty?.('addEventListener')) {
return;
}

Expand Down
4 changes: 2 additions & 2 deletions packages/browser/src/integrations/contextlines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ function addSourceContext(event: Event, contextLines: number): Event {
return event;
}

const exceptions = event.exception && event.exception.values;
if (!exceptions || !exceptions.length) {
const exceptions = event.exception?.values;
if (!exceptions?.length) {
return event;
}

Expand Down
12 changes: 8 additions & 4 deletions packages/browser/src/integrations/httpcontext.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { defineIntegration } from '@sentry/core';
import { defineIntegration, getLocationHref } from '@sentry/core';
import { WINDOW } from '../helpers';

/**
Expand All @@ -15,16 +15,20 @@ export const httpContextIntegration = defineIntegration(() => {
}

// grab as much info as exists and add it to the event
const url = (event.request && event.request.url) || (WINDOW.location && WINDOW.location.href);
const url = event.request?.url || getLocationHref();
const { referrer } = WINDOW.document || {};
const { userAgent } = WINDOW.navigator || {};

const headers = {
...(event.request && event.request.headers),
...event.request?.headers,
...(referrer && { Referer: referrer }),
...(userAgent && { 'User-Agent': userAgent }),
};
const request = { ...event.request, ...(url && { url }), headers };
const request = {
...event.request,
...(url && { url }),
headers,
};

event.request = request;
},
Expand Down
6 changes: 3 additions & 3 deletions packages/browser/src/profiling/integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ const _browserProfilingIntegration = (() => {

for (const profiledTransaction of profiledTransactionEvents) {
const context = profiledTransaction?.contexts;
const profile_id = context && context['profile'] && context['profile']['profile_id'];
const start_timestamp = context && context['profile'] && context['profile']['start_timestamp'];
const profile_id = context?.profile?.['profile_id'];
const start_timestamp = context?.profile?.['start_timestamp'];

if (typeof profile_id !== 'string') {
DEBUG_BUILD && logger.log('[Profiling] cannot find profile for a span without a profile context');
Expand All @@ -64,7 +64,7 @@ const _browserProfilingIntegration = (() => {
}

// Remove the profile from the span context before sending, relay will take care of the rest.
if (context && context['profile']) {
if (context?.profile) {
delete context.profile;
}

Expand Down
Loading
Loading