Skip to content

Commit

Permalink
fix(angular): run tracing stuff outside Angular
Browse files Browse the repository at this point in the history
This commit updates all tracing functionality to run outside the Angular zone.
Before this change, it hindered server-side rendering and hydration, causing instability
in the app. The app achieves stability when there are no micro/macro tasks running. As a
result, the HTML can now be serialized and sent to the client.
  • Loading branch information
arturovt committed Apr 23, 2024
1 parent 7eb000c commit d9a67b4
Showing 1 changed file with 27 additions and 23 deletions.
50 changes: 27 additions & 23 deletions packages/angular/src/tracing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,14 @@ export class TraceService implements OnDestroy {
if (client) {
// see comment in `_isPageloadOngoing` for rationale
if (!this._isPageloadOngoing()) {
startBrowserTracingNavigationSpan(client, {
name: strippedUrl,
attributes: {
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.angular',
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
},
runOutsideAngular(() => {
startBrowserTracingNavigationSpan(client, {
name: strippedUrl,
attributes: {
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.angular',
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
},
});
});
} else {
// The first time we end up here, we set the pageload flag to false
Expand All @@ -104,7 +106,7 @@ export class TraceService implements OnDestroy {
}

this._routingSpan =
startInactiveSpan({
runOutsideAngular(() => startInactiveSpan({
name: `${navigationEvent.url}`,
op: ANGULAR_ROUTING_OP,
attributes: {
Expand All @@ -115,7 +117,7 @@ export class TraceService implements OnDestroy {
navigationTrigger: navigationEvent.navigationTrigger,
}),
},
}) || null;
})) || null;

return;
}
Expand Down Expand Up @@ -252,11 +254,11 @@ export class TraceDirective implements OnInit, AfterViewInit {
}

if (getActiveSpan()) {
this._tracingSpan = startInactiveSpan({
this._tracingSpan = runOutsideAngular(() => startInactiveSpan({
name: `<${this.componentName}>`,
op: ANGULAR_INIT_OP,
attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.angular.trace_directive' },
});
}));
}
}

Expand All @@ -266,7 +268,7 @@ export class TraceDirective implements OnInit, AfterViewInit {
*/
public ngAfterViewInit(): void {
if (this._tracingSpan) {
this._tracingSpan.end();
runOutsideAngular(() => this._tracingSpan!.end());
}
}
}
Expand Down Expand Up @@ -298,14 +300,14 @@ export function TraceClass(options?: TraceClassOptions): ClassDecorator {
const originalOnInit = target.prototype.ngOnInit;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
target.prototype.ngOnInit = function (...args: any[]): ReturnType<typeof originalOnInit> {
tracingSpan = startInactiveSpan({
tracingSpan = runOutsideAngular(() => startInactiveSpan({
onlyIfParent: true,
name: `<${options && options.name ? options.name : 'unnamed'}>`,
op: ANGULAR_INIT_OP,
attributes: {
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.angular.trace_class_decorator',
},
});
}));

if (originalOnInit) {
return originalOnInit.apply(this, args);
Expand All @@ -316,7 +318,7 @@ export function TraceClass(options?: TraceClassOptions): ClassDecorator {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
target.prototype.ngAfterViewInit = function (...args: any[]): ReturnType<typeof originalAfterViewInit> {
if (tracingSpan) {
tracingSpan.end();
runOutsideAngular(() => tracingSpan.end());
}
if (originalAfterViewInit) {
return originalAfterViewInit.apply(this, args);
Expand Down Expand Up @@ -344,15 +346,17 @@ export function TraceMethod(options?: TraceMethodOptions): MethodDecorator {
descriptor.value = function (...args: any[]): ReturnType<typeof originalMethod> {
const now = timestampInSeconds();

startInactiveSpan({
onlyIfParent: true,
name: `<${options && options.name ? options.name : 'unnamed'}>`,
op: `${ANGULAR_OP}.${String(propertyKey)}`,
startTime: now,
attributes: {
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.angular.trace_method_decorator',
},
}).end(now);
runOutsideAngular(() => {
startInactiveSpan({
onlyIfParent: true,
name: `<${options && options.name ? options.name : 'unnamed'}>`,
op: `${ANGULAR_OP}.${String(propertyKey)}`,
startTime: now,
attributes: {
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.angular.trace_method_decorator',
},
}).end(now);
});

if (originalMethod) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
Expand Down

0 comments on commit d9a67b4

Please sign in to comment.