Skip to content

Commit 1a7626f

Browse files
feat(node): Add docs for async context apis (#6641)
Co-authored-by: Shana Matthews <shana.l.matthews@gmail.com>
1 parent d76fe81 commit 1a7626f

File tree

8 files changed

+56
-28
lines changed

8 files changed

+56
-28
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
title: Async Context
3+
sidebar_order: 80
4+
description: "Learn more about how to isolate Sentry scope and breadcrumbs across requests."
5+
---
6+
7+
You can use the `runWithAsyncContext` method to isolate Sentry scope and breadcrumbs to a single request if you are using SDK v7.48.0 or higher. This is useful if you are finding that breadcrumbs and scope are leaking across requests.
8+
9+
```js
10+
const Sentry = require("@sentry/node");
11+
12+
function requestHandlerMiddleware(req, res, next) {
13+
// Any breadcrumbs or tags added will be isolated to the request
14+
return Sentry.runWithAsyncContext(() => {
15+
return next(req, res);
16+
});
17+
}
18+
```
19+
20+
Under the hood, the SDK uses Node's [AsyncLocalStorage API](https://nodejs.org/api/async_context.html#class-asynclocalstorage) to perform the isolation.
21+
22+
On lower SDK versions you'll have to use [domains](https://nodejs.org/api/domain.html) to isolate Sentry scope and breadcrumbs to a single request.
23+
24+
```js
25+
const domain = require("domain");
26+
27+
function myRequestHandler(req, res, next) {
28+
const localDomain = domain.create();
29+
return localDomain.bind(() => {
30+
return next(req, res);
31+
})();
32+
}
33+
```

src/platforms/node/guides/express/index.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,8 @@ Sentry.init({
167167
tracesSampleRate: 1.0,
168168
});
169169

170-
// RequestHandler creates a separate execution context using domains, so that every
171-
// transaction/span/breadcrumb is attached to its own Hub instance
170+
// RequestHandler creates a separate execution context, so that all
171+
// transactions/spans/breadcrumbs are isolated across requests
172172
app.use(Sentry.Handlers.requestHandler());
173173
// TracingHandler creates a trace for every incoming request
174174
app.use(Sentry.Handlers.tracingHandler());

src/platforms/node/guides/express/performance/index.mdx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ Sentry.init({
3535
tracesSampleRate: 1.0,
3636
});
3737

38-
// RequestHandler creates a separate execution context using domains, so that every
39-
// transaction/span/breadcrumb is attached to its own Hub instance
38+
// RequestHandler creates a separate execution context, so that all
39+
// transactions/spans/breadcrumbs are isolated across requests
4040
app.use(Sentry.Handlers.requestHandler());
4141
// TracingHandler creates a trace for every incoming request
4242
app.use(Sentry.Handlers.tracingHandler());
@@ -132,6 +132,7 @@ app.get("/success", function successHandler(req, res) {
132132
## Connecting Services
133133

134134
If you are also using Performance Monitoring for [JavaScript](/platforms/javascript/performance/), depending on where your request originates, you can connect traces:
135+
135136
1. For requests that start in your backend, by [adding a meta tag](/platforms/javascript/performance/connect-services/#pageload) in your HTML template that contains tracing information.
136137
2. For requests that start in JavaScript, by the SDK [setting a header](/platforms/javascript/performance/connect-services/#navigation-and-other-xhr-requests) on requests to your backend.
137138

src/platforms/node/guides/express/performance/instrumentation/automatic-instrumentation.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ Sentry.init({
3737
tracesSampleRate: 1.0,
3838
});
3939

40-
// RequestHandler creates a separate execution context using domains, so that every
41-
// transaction/span/breadcrumb is attached to its own Hub instance
40+
// RequestHandler creates a separate execution context, so that all
41+
// transactions/spans/breadcrumbs are isolated across requests
4242
app.use(Sentry.Handlers.requestHandler());
4343
// TracingHandler creates a trace for every incoming request
4444
app.use(Sentry.Handlers.tracingHandler());

src/platforms/node/guides/koa/index.mdx

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ const Sentry = require("@sentry/node");
4949
const { stripUrlQueryAndFragment } = require("@sentry/utils");
5050
const Koa = require("koa");
5151
const app = new Koa();
52-
const domain = require("domain");
5352

5453
Sentry.init({
5554
dsn: "___PUBLIC_DSN___",
@@ -64,27 +63,20 @@ Sentry.init({
6463
],
6564
});
6665

67-
// not mandatory, but adding domains does help a lot with breadcrumbs
6866
const requestHandler = (ctx, next) => {
6967
return new Promise((resolve, reject) => {
70-
const local = domain.create();
71-
local.add(ctx);
72-
local.on("error", err => {
73-
ctx.status = err.status || 500;
74-
ctx.body = err.message;
75-
ctx.app.emit("error", err, ctx);
76-
reject(err);
77-
});
78-
local.run(async () => {
79-
Sentry.getCurrentHub().configureScope(scope =>
68+
Sentry.runWithAsyncContext(async () => {
69+
const hub = Sentry.getCurrentHub();
70+
hub.configureScope(scope =>
8071
scope.addEventProcessor(event =>
8172
Sentry.addRequestDataToEvent(event, ctx.request, {
8273
include: {
8374
user: false,
8475
},
85-
});
86-
);
76+
})
77+
)
8778
);
79+
8880
await next();
8981
resolve();
9082
});
@@ -99,7 +91,9 @@ const tracingMiddleWare = async (ctx, next) => {
9991
// connect to trace of upstream app
10092
let traceparentData;
10193
if (ctx.request.get("sentry-trace")) {
102-
traceparentData = Sentry.extractTraceparentData(ctx.request.get("sentry-trace"));
94+
traceparentData = Sentry.extractTraceparentData(
95+
ctx.request.get("sentry-trace")
96+
);
10397
}
10498

10599
const transaction = Sentry.startTransaction({
@@ -136,7 +130,7 @@ app.use(tracingMiddleWare);
136130

137131
// usual error handler
138132
app.on("error", (err, ctx) => {
139-
Sentry.withScope((scope) => {
133+
Sentry.withScope(scope => {
140134
scope.addEventProcessor(event => {
141135
return Sentry.addRequestDataToEvent(event, ctx.request);
142136
});

src/platforms/node/guides/serverless-cloud/index.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,8 @@ Sentry.init({
142142
// tracesSampleRate: parseFloat(params.SENTRY_TRACES_SAMPLE_RATE),
143143
});
144144

145-
// RequestHandler creates a separate execution context using domains, so that every
146-
// transaction/span/breadcrumb is attached to its own Hub instance
145+
// RequestHandler creates a separate execution context, so that all
146+
// transactions/spans/breadcrumbs are isolated across requests
147147
api.use(Sentry.Handlers.requestHandler());
148148
// TracingHandler creates a trace for every incoming request
149149
api.use(Sentry.Handlers.tracingHandler());

src/wizard/node/express.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ Sentry.init({
4444
tracesSampleRate: 1.0,
4545
});
4646

47-
// RequestHandler creates a separate execution context using domains, so that every
48-
// transaction/span/breadcrumb is attached to its own Hub instance
47+
// RequestHandler creates a separate execution context, so that all
48+
// transactions/spans/breadcrumbs are isolated across requests
4949
app.use(Sentry.Handlers.requestHandler());
5050
// TracingHandler creates a trace for every incoming request
5151
app.use(Sentry.Handlers.tracingHandler());

src/wizard/node/serverlesscloud.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ Sentry.init({
4343
// tracesSampleRate: parseFloat(params.SENTRY_TRACES_SAMPLE_RATE),
4444
});
4545

46-
// RequestHandler creates a separate execution context using domains, so that every
47-
// transaction/span/breadcrumb is attached to its own Hub instance
46+
// RequestHandler creates a separate execution context, so that all
47+
// transactions/spans/breadcrumbs are isolated across requests
4848
api.use(Sentry.Handlers.requestHandler());
4949
// TracingHandler creates a trace for every incoming request
5050
api.use(Sentry.Handlers.tracingHandler());

0 commit comments

Comments
 (0)