Skip to content

Commit 1048a43

Browse files
mydeaLms24
andauthored
ref: Use optional chaining where possible (#14954)
This PR updates our code to use optional chaining, where possible. This was mostly search-and-replace by `xx && xx.` regex, so there may def. be some remaining places, but this should cover a good amount of usage. --------- Co-authored-by: Lukas Stracke <lukas.stracke@sentry.io>
1 parent 6779dfe commit 1048a43

File tree

123 files changed

+216
-232
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

123 files changed

+216
-232
lines changed

Diff for: dev-packages/browser-integration-tests/loader-suites/loader/noOnLoad/customOnErrorHandler/subject.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ const oldOnError = window.onerror;
22

33
window.onerror = function () {
44
console.log('custom error');
5-
oldOnError && oldOnError.apply(this, arguments);
5+
oldOnError?.apply(this, arguments);
66
};
77

88
window.doSomethingWrong();

Diff for: dev-packages/browser-integration-tests/suites/integrations/featureFlags/launchdarkly/init.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Sentry.init({
1313
// Also, no SDK has mock utils for FlagUsedHandler's.
1414
const MockLaunchDarkly = {
1515
initialize(_clientId, context, options) {
16-
const flagUsedHandler = options && options.inspectors ? options.inspectors[0].method : undefined;
16+
const flagUsedHandler = options.inspectors ? options.inspectors[0].method : undefined;
1717

1818
return {
1919
variation(key, defaultValue) {

Diff for: dev-packages/browser-integration-tests/suites/old-sdk-interop/acs/getCurrentScope/subject.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const sentryCarrier = window && window.__SENTRY__;
1+
const sentryCarrier = window?.__SENTRY__;
22

33
/**
44
* Simulate an old pre v8 SDK obtaining the hub from the global sentry carrier

Diff for: dev-packages/browser-integration-tests/suites/old-sdk-interop/hub/isOlderThan/subject.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const sentryCarrier = window && window.__SENTRY__;
1+
const sentryCarrier = window?.__SENTRY__;
22

33
/**
44
* Simulate an old pre v8 SDK obtaining the hub from the global sentry carrier

Diff for: dev-packages/e2e-tests/test-applications/create-remix-app-express-legacy/app/routes/navigate.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export default function LoaderError() {
1414

1515
return (
1616
<div>
17-
<h1>{data && data.test ? data.test : 'Not Found'}</h1>
17+
<h1>{data?.test ? data.test : 'Not Found'}</h1>
1818
</div>
1919
);
2020
}

Diff for: dev-packages/e2e-tests/test-applications/create-remix-app-express-vite-dev/app/routes/navigate.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export default function LoaderError() {
1414

1515
return (
1616
<div>
17-
<h1>{data && data.test ? data.test : 'Not Found'}</h1>
17+
<h1>{data?.test ? data.test : 'Not Found'}</h1>
1818
</div>
1919
);
2020
}

Diff for: dev-packages/e2e-tests/test-applications/create-remix-app-express/app/routes/navigate.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export default function LoaderError() {
1414

1515
return (
1616
<div>
17-
<h1>{data && data.test ? data.test : 'Not Found'}</h1>
17+
<h1>{data?.test ? data.test : 'Not Found'}</h1>
1818
</div>
1919
);
2020
}

Diff for: dev-packages/e2e-tests/test-applications/create-remix-app-legacy/app/routes/navigate.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export default function LoaderError() {
1414

1515
return (
1616
<div>
17-
<h1>{data && data.test ? data.test : 'Not Found'}</h1>
17+
<h1>{data?.test ? data.test : 'Not Found'}</h1>
1818
</div>
1919
);
2020
}

Diff for: dev-packages/e2e-tests/test-applications/create-remix-app-v2-legacy/app/routes/navigate.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export default function LoaderError() {
1414

1515
return (
1616
<div>
17-
<h1>{data && data.test ? data.test : 'Not Found'}</h1>
17+
<h1>{data?.test ? data.test : 'Not Found'}</h1>
1818
</div>
1919
);
2020
}

Diff for: dev-packages/e2e-tests/test-applications/create-remix-app-v2/app/routes/navigate.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export default function LoaderError() {
1414

1515
return (
1616
<div>
17-
<h1>{data && data.test ? data.test : 'Not Found'}</h1>
17+
<h1>{data?.test ? data.test : 'Not Found'}</h1>
1818
</div>
1919
);
2020
}

Diff for: dev-packages/e2e-tests/test-applications/create-remix-app/app/routes/navigate.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export default function LoaderError() {
1414

1515
return (
1616
<div>
17-
<h1>{data && data.test ? data.test : 'Not Found'}</h1>
17+
<h1>{data?.test ? data.test : 'Not Found'}</h1>
1818
</div>
1919
);
2020
}

Diff for: dev-packages/e2e-tests/test-applications/ember-classic/app/initializers/deprecation.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { registerDeprecationHandler } from '@ember/debug';
22

33
export function initialize(): void {
44
registerDeprecationHandler((message, options, next) => {
5-
if (options && options.until && options.until !== '3.0.0') {
5+
if (options?.until && options.until !== '3.0.0') {
66
return;
77
} else {
88
next(message, options);

Diff for: packages/angular/patch-vitest.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -182,22 +182,20 @@ function isAngularFixture(val: any): boolean {
182182
*/
183183
function fixtureVitestSerializer(fixture: any) {
184184
// * Get Component meta data
185-
const componentType = (
186-
fixture && fixture.componentType ? fixture.componentType : fixture.componentRef.componentType
187-
) as any;
185+
const componentType = (fixture?.componentType ? fixture.componentType : fixture.componentRef.componentType) as any;
188186

189187
let inputsData: string = '';
190188

191189
const selector = Reflect.getOwnPropertyDescriptor(componentType, '__annotations__')?.value[0].selector;
192190

193-
if (componentType && componentType.propDecorators) {
191+
if (componentType?.propDecorators) {
194192
inputsData = Object.entries(componentType.propDecorators)
195193
.map(([key, value]) => `${key}="${value}"`)
196194
.join('');
197195
}
198196

199197
// * Get DOM Elements
200-
const divElement = fixture && fixture.nativeElement ? fixture.nativeElement : fixture.location.nativeElement;
198+
const divElement = fixture?.nativeElement ? fixture.nativeElement : fixture.location.nativeElement;
201199

202200
// * Convert string data to HTML data
203201
const doc = new DOMParser().parseFromString(

Diff for: packages/angular/src/sdk.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export function init(options: BrowserOptions): Client | undefined {
6262
function checkAndSetAngularVersion(): void {
6363
const ANGULAR_MINIMUM_VERSION = 14;
6464

65-
const angularVersion = VERSION && VERSION.major ? parseInt(VERSION.major, 10) : undefined;
65+
const angularVersion = VERSION?.major && parseInt(VERSION.major, 10);
6666

6767
if (angularVersion) {
6868
if (angularVersion < ANGULAR_MINIMUM_VERSION) {

Diff for: packages/angular/src/tracing.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ export function TraceClass(options?: TraceClassOptions): ClassDecorator {
322322
tracingSpan = runOutsideAngular(() =>
323323
startInactiveSpan({
324324
onlyIfParent: true,
325-
name: `<${options && options.name ? options.name : 'unnamed'}>`,
325+
name: `<${options?.name || 'unnamed'}>`,
326326
op: ANGULAR_INIT_OP,
327327
attributes: {
328328
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.angular.trace_class_decorator',
@@ -367,7 +367,7 @@ export function TraceMethod(options?: TraceMethodOptions): MethodDecorator {
367367
runOutsideAngular(() => {
368368
startInactiveSpan({
369369
onlyIfParent: true,
370-
name: `<${options && options.name ? options.name : 'unnamed'}>`,
370+
name: `<${options?.name ? options.name : 'unnamed'}>`,
371371
op: `${ANGULAR_OP}.${String(propertyKey)}`,
372372
startTime: now,
373373
attributes: {
@@ -397,9 +397,9 @@ export function TraceMethod(options?: TraceMethodOptions): MethodDecorator {
397397
export function getParameterizedRouteFromSnapshot(route?: ActivatedRouteSnapshot | null): string {
398398
const parts: string[] = [];
399399

400-
let currentRoute = route && route.firstChild;
400+
let currentRoute = route?.firstChild;
401401
while (currentRoute) {
402-
const path = currentRoute && currentRoute.routeConfig && currentRoute.routeConfig.path;
402+
const path = currentRoute?.routeConfig && currentRoute.routeConfig.path;
403403
if (path === null || path === undefined) {
404404
break;
405405
}

Diff for: packages/astro/src/server/middleware.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,13 @@ async function instrumentRequest(
8787
isolationScope?: Scope,
8888
): Promise<Response> {
8989
// Make sure we don't accidentally double wrap (e.g. user added middleware and integration auto added it)
90-
const locals = ctx.locals as AstroLocalsWithSentry;
91-
if (locals && locals.__sentry_wrapped__) {
90+
const locals = ctx.locals as AstroLocalsWithSentry | undefined;
91+
if (locals?.__sentry_wrapped__) {
9292
return next();
9393
}
94-
addNonEnumerableProperty(locals, '__sentry_wrapped__', true);
94+
if (locals) {
95+
addNonEnumerableProperty(locals, '__sentry_wrapped__', true);
96+
}
9597

9698
const isDynamicPageRequest = checkIsDynamicPageRequest(ctx);
9799

@@ -164,7 +166,7 @@ async function instrumentRequest(
164166
const client = getClient();
165167
const contentType = originalResponse.headers.get('content-type');
166168

167-
const isPageloadRequest = contentType && contentType.startsWith('text/html');
169+
const isPageloadRequest = contentType?.startsWith('text/html');
168170
if (!isPageloadRequest || !client) {
169171
return originalResponse;
170172
}

Diff for: packages/aws-serverless/src/sdk.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ export function wrapHandler<TEvent, TResult>(
323323
throw e;
324324
} finally {
325325
clearTimeout(timeoutWarningTimer);
326-
if (span && span.isRecording()) {
326+
if (span?.isRecording()) {
327327
span.end();
328328
}
329329
await flush(options.flushTimeout).catch(e => {

Diff for: packages/aws-serverless/src/utils.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export function getAwsTraceData(event: HandlerEvent, context?: HandlerContext):
5353
baggage: headers.baggage,
5454
};
5555

56-
if (context && context.clientContext && context.clientContext.Custom) {
56+
if (context?.clientContext?.Custom) {
5757
const customContext: Record<string, unknown> = context.clientContext.Custom;
5858
const sentryTrace = isString(customContext['sentry-trace']) ? customContext['sentry-trace'] : undefined;
5959

Diff for: packages/browser-utils/src/instrument/dom.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@ export function instrumentDOM(): void {
6464
// guaranteed to fire at least once.)
6565
['EventTarget', 'Node'].forEach((target: string) => {
6666
const globalObject = WINDOW as unknown as Record<string, { prototype?: object }>;
67-
const targetObj = globalObject[target];
68-
const proto = targetObj && targetObj.prototype;
67+
const proto = globalObject[target]?.prototype;
6968

7069
// eslint-disable-next-line no-prototype-builtins
7170
if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) {

Diff for: packages/browser-utils/src/metrics/browserMetrics.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,7 @@ function _setWebVitalAttributes(span: Span): void {
674674
}
675675

676676
// See: https://developer.mozilla.org/en-US/docs/Web/API/LayoutShift
677-
if (_clsEntry && _clsEntry.sources) {
677+
if (_clsEntry?.sources) {
678678
_clsEntry.sources.forEach((source, index) =>
679679
span.setAttribute(`cls.source.${index + 1}`, htmlTreeAsString(source.node)),
680680
);

Diff for: packages/browser-utils/src/metrics/cls.ts

+8-6
Original file line numberDiff line numberDiff line change
@@ -77,26 +77,28 @@ export function trackClsAsStandaloneSpan(): void {
7777
});
7878

7979
const activeSpan = getActiveSpan();
80-
const rootSpan = activeSpan && getRootSpan(activeSpan);
81-
const spanJSON = rootSpan && spanToJSON(rootSpan);
82-
if (spanJSON && spanJSON.op === 'pageload') {
83-
pageloadSpanId = rootSpan.spanContext().spanId;
80+
if (activeSpan) {
81+
const rootSpan = getRootSpan(activeSpan);
82+
const spanJSON = spanToJSON(rootSpan);
83+
if (spanJSON.op === 'pageload') {
84+
pageloadSpanId = rootSpan.spanContext().spanId;
85+
}
8486
}
8587
}, 0);
8688
}
8789

8890
function sendStandaloneClsSpan(clsValue: number, entry: LayoutShift | undefined, pageloadSpanId: string) {
8991
DEBUG_BUILD && logger.log(`Sending CLS span (${clsValue})`);
9092

91-
const startTime = msToSec((browserPerformanceTimeOrigin || 0) + ((entry && entry.startTime) || 0));
93+
const startTime = msToSec((browserPerformanceTimeOrigin || 0) + (entry?.startTime || 0));
9294
const routeName = getCurrentScope().getScopeData().transactionName;
9395

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

9698
const attributes: SpanAttributes = dropUndefinedKeys({
9799
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.browser.cls',
98100
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'ui.webvital.cls',
99-
[SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME]: (entry && entry.duration) || 0,
101+
[SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME]: entry?.duration || 0,
100102
// attach the pageload span id to the CLS span so that we can link them in the UI
101103
'sentry.pageload.span_id': pageloadSpanId,
102104
});

Diff for: packages/browser-utils/src/metrics/utils.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export function startStandaloneWebVitalSpan(options: StandaloneWebVitalSpanOptio
7878
// We need to get the replay, user, and activeTransaction from the current scope
7979
// so that we can associate replay id, profile id, and a user display to the span
8080
const replay = client.getIntegrationByName<Integration & { getReplayId: () => string }>('Replay');
81-
const replayId = replay && replay.getReplayId();
81+
const replayId = replay?.getReplayId();
8282

8383
const scope = getCurrentScope();
8484

@@ -124,7 +124,7 @@ export function startStandaloneWebVitalSpan(options: StandaloneWebVitalSpanOptio
124124
/** Get the browser performance API. */
125125
export function getBrowserPerformanceAPI(): Performance | undefined {
126126
// @ts-expect-error we want to make sure all of these are available, even if TS is sure they are
127-
return WINDOW && WINDOW.addEventListener && WINDOW.performance;
127+
return WINDOW.addEventListener && WINDOW.performance;
128128
}
129129

130130
/**

Diff for: packages/browser-utils/src/metrics/web-vitals/lib/getActivationStart.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@ import { getNavigationEntry } from './getNavigationEntry';
1818

1919
export const getActivationStart = (): number => {
2020
const navEntry = getNavigationEntry();
21-
return (navEntry && navEntry.activationStart) || 0;
21+
return navEntry?.activationStart || 0;
2222
};

Diff for: packages/browser/src/eventbuilder.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ function eventFromPlainObject(
5555
isUnhandledRejection?: boolean,
5656
): Event {
5757
const client = getClient();
58-
const normalizeDepth = client && client.getOptions().normalizeDepth;
58+
const normalizeDepth = client?.getOptions().normalizeDepth;
5959

6060
// If we can, we extract an exception from the object properties
6161
const errorFromProp = getErrorPropertyFromObject(exception);
@@ -178,7 +178,7 @@ function isWebAssemblyException(exception: unknown): exception is WebAssembly.Ex
178178
* Usually, this is the `name` property on Error objects but WASM errors need to be treated differently.
179179
*/
180180
export function extractType(ex: Error & { message: { error?: Error } }): string | undefined {
181-
const name = ex && ex.name;
181+
const name = ex?.name;
182182

183183
// The name for WebAssembly.Exception Errors needs to be extracted differently.
184184
// Context: https://github.com/getsentry/sentry-javascript/issues/13787
@@ -197,7 +197,7 @@ export function extractType(ex: Error & { message: { error?: Error } }): string
197197
* In this specific case we try to extract stacktrace.message.error.message
198198
*/
199199
export function extractMessage(ex: Error & { message: { error?: Error } }): string {
200-
const message = ex && ex.message;
200+
const message = ex?.message;
201201

202202
if (!message) {
203203
return 'No error message';
@@ -225,11 +225,11 @@ export function eventFromException(
225225
hint?: EventHint,
226226
attachStacktrace?: boolean,
227227
): PromiseLike<Event> {
228-
const syntheticException = (hint && hint.syntheticException) || undefined;
228+
const syntheticException = hint?.syntheticException || undefined;
229229
const event = eventFromUnknownInput(stackParser, exception, syntheticException, attachStacktrace);
230230
addExceptionMechanism(event); // defaults to { type: 'generic', handled: true }
231231
event.level = 'error';
232-
if (hint && hint.event_id) {
232+
if (hint?.event_id) {
233233
event.event_id = hint.event_id;
234234
}
235235
return resolvedSyncPromise(event);
@@ -246,10 +246,10 @@ export function eventFromMessage(
246246
hint?: EventHint,
247247
attachStacktrace?: boolean,
248248
): PromiseLike<Event> {
249-
const syntheticException = (hint && hint.syntheticException) || undefined;
249+
const syntheticException = hint?.syntheticException || undefined;
250250
const event = eventFromString(stackParser, message, syntheticException, attachStacktrace);
251251
event.level = level;
252-
if (hint && hint.event_id) {
252+
if (hint?.event_id) {
253253
event.event_id = hint.event_id;
254254
}
255255
return resolvedSyncPromise(event);

Diff for: packages/browser/src/integrations/breadcrumbs.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ function _getFetchBreadcrumbHandler(client: Client): (handlerData: HandlerDataFe
313313

314314
breadcrumbData.request_body_size = handlerData.fetchData.request_body_size;
315315
breadcrumbData.response_body_size = handlerData.fetchData.response_body_size;
316-
breadcrumbData.status_code = response && response.status;
316+
breadcrumbData.status_code = response?.status;
317317

318318
const hint: FetchBreadcrumbHint = {
319319
input: handlerData.args,

Diff for: packages/browser/src/integrations/browserapierrors.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,7 @@ function _wrapXHR(originalSend: () => void): () => void {
163163

164164
function _wrapEventTarget(target: string): void {
165165
const globalObject = WINDOW as unknown as Record<string, { prototype?: object }>;
166-
const targetObj = globalObject[target];
167-
const proto = targetObj && targetObj.prototype;
166+
const proto = globalObject[target]?.prototype;
168167

169168
// eslint-disable-next-line no-prototype-builtins
170169
if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) {

Diff for: packages/browser/src/integrations/contextlines.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ function addSourceContext(event: Event, contextLines: number): Event {
6565

6666
exceptions.forEach(exception => {
6767
const stacktrace = exception.stacktrace;
68-
if (stacktrace && stacktrace.frames) {
68+
if (stacktrace?.frames) {
6969
stacktrace.frames = stacktrace.frames.map(frame =>
7070
applySourceContextToFrame(frame, htmlLines, htmlFilename, contextLines),
7171
);

Diff for: packages/browser/src/integrations/globalhandlers.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ function globalHandlerLog(type: string): void {
194194

195195
function getOptions(): { stackParser: StackParser; attachStacktrace?: boolean } {
196196
const client = getClient<BrowserClient>();
197-
const options = (client && client.getOptions()) || {
197+
const options = client?.getOptions() || {
198198
stackParser: () => [],
199199
attachStacktrace: false,
200200
};

Diff for: packages/browser/src/integrations/spotlight.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,6 @@ export function isSpotlightInteraction(event: Event): boolean {
8484
event.contexts &&
8585
event.contexts.trace &&
8686
event.contexts.trace.op === 'ui.action.click' &&
87-
event.spans.some(({ description }) => description && description.includes('#sentry-spotlight')),
87+
event.spans.some(({ description }) => description?.includes('#sentry-spotlight')),
8888
);
8989
}

Diff for: packages/browser/src/profiling/integration.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ const _browserProfilingIntegration = (() => {
4949
const profilesToAddToEnvelope: Profile[] = [];
5050

5151
for (const profiledTransaction of profiledTransactionEvents) {
52-
const context = profiledTransaction && profiledTransaction.contexts;
52+
const context = profiledTransaction?.contexts;
5353
const profile_id = context && context['profile'] && context['profile']['profile_id'];
5454
const start_timestamp = context && context['profile'] && context['profile']['start_timestamp'];
5555

0 commit comments

Comments
 (0)