chub-dev 0.1.0 → 0.1.2-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -0
- package/bin/chub-mcp +2 -0
- package/dist/airtable/docs/database/javascript/DOC.md +1437 -0
- package/dist/airtable/docs/database/python/DOC.md +1735 -0
- package/dist/amplitude/docs/analytics/javascript/DOC.md +1282 -0
- package/dist/amplitude/docs/analytics/python/DOC.md +1199 -0
- package/dist/anthropic/docs/claude-api/javascript/DOC.md +503 -0
- package/dist/anthropic/docs/claude-api/python/DOC.md +389 -0
- package/dist/asana/docs/tasks/DOC.md +1396 -0
- package/dist/assemblyai/docs/transcription/DOC.md +1043 -0
- package/dist/atlassian/docs/confluence/javascript/DOC.md +1347 -0
- package/dist/atlassian/docs/confluence/python/DOC.md +1604 -0
- package/dist/auth0/docs/identity/javascript/DOC.md +968 -0
- package/dist/auth0/docs/identity/python/DOC.md +1199 -0
- package/dist/aws/docs/s3/javascript/DOC.md +1773 -0
- package/dist/aws/docs/s3/python/DOC.md +1807 -0
- package/dist/binance/docs/trading/javascript/DOC.md +1315 -0
- package/dist/binance/docs/trading/python/DOC.md +1454 -0
- package/dist/braintree/docs/gateway/javascript/DOC.md +1278 -0
- package/dist/braintree/docs/gateway/python/DOC.md +1179 -0
- package/dist/chromadb/docs/embeddings-db/javascript/DOC.md +1263 -0
- package/dist/chromadb/docs/embeddings-db/python/DOC.md +1707 -0
- package/dist/clerk/docs/auth/javascript/DOC.md +1220 -0
- package/dist/clerk/docs/auth/python/DOC.md +274 -0
- package/dist/cloudflare/docs/workers/javascript/DOC.md +918 -0
- package/dist/cloudflare/docs/workers/python/DOC.md +994 -0
- package/dist/cockroachdb/docs/distributed-db/DOC.md +1500 -0
- package/dist/cohere/docs/llm/DOC.md +1335 -0
- package/dist/datadog/docs/monitoring/javascript/DOC.md +1740 -0
- package/dist/datadog/docs/monitoring/python/DOC.md +1815 -0
- package/dist/deepgram/docs/speech/javascript/DOC.md +885 -0
- package/dist/deepgram/docs/speech/python/DOC.md +685 -0
- package/dist/deepl/docs/translation/javascript/DOC.md +887 -0
- package/dist/deepl/docs/translation/python/DOC.md +944 -0
- package/dist/deepseek/docs/llm/DOC.md +1220 -0
- package/dist/directus/docs/headless-cms/javascript/DOC.md +1128 -0
- package/dist/directus/docs/headless-cms/python/DOC.md +1276 -0
- package/dist/discord/docs/bot/javascript/DOC.md +1090 -0
- package/dist/discord/docs/bot/python/DOC.md +1130 -0
- package/dist/elasticsearch/docs/search/DOC.md +1634 -0
- package/dist/elevenlabs/docs/text-to-speech/javascript/DOC.md +336 -0
- package/dist/elevenlabs/docs/text-to-speech/python/DOC.md +552 -0
- package/dist/firebase/docs/auth/DOC.md +1015 -0
- package/dist/gemini/docs/genai/javascript/DOC.md +691 -0
- package/dist/gemini/docs/genai/python/DOC.md +555 -0
- package/dist/github/docs/octokit/DOC.md +1560 -0
- package/dist/google/docs/bigquery/javascript/DOC.md +1688 -0
- package/dist/google/docs/bigquery/python/DOC.md +1503 -0
- package/dist/hubspot/docs/crm/javascript/DOC.md +1805 -0
- package/dist/hubspot/docs/crm/python/DOC.md +2033 -0
- package/dist/huggingface/docs/transformers/DOC.md +948 -0
- package/dist/intercom/docs/messaging/javascript/DOC.md +1844 -0
- package/dist/intercom/docs/messaging/python/DOC.md +1797 -0
- package/dist/jira/docs/issues/javascript/DOC.md +1420 -0
- package/dist/jira/docs/issues/python/DOC.md +1492 -0
- package/dist/kafka/docs/streaming/javascript/DOC.md +1671 -0
- package/dist/kafka/docs/streaming/python/DOC.md +1464 -0
- package/dist/landingai-ade/docs/api/DOC.md +620 -0
- package/dist/landingai-ade/docs/sdk/python/DOC.md +489 -0
- package/dist/landingai-ade/docs/sdk/typescript/DOC.md +542 -0
- package/dist/landingai-ade/skills/SKILL.md +489 -0
- package/dist/launchdarkly/docs/feature-flags/javascript/DOC.md +1191 -0
- package/dist/launchdarkly/docs/feature-flags/python/DOC.md +1671 -0
- package/dist/linear/docs/tracker/DOC.md +1554 -0
- package/dist/livekit/docs/realtime/javascript/DOC.md +303 -0
- package/dist/livekit/docs/realtime/python/DOC.md +163 -0
- package/dist/mailchimp/docs/marketing/DOC.md +1420 -0
- package/dist/meilisearch/docs/search/DOC.md +1241 -0
- package/dist/microsoft/docs/onedrive/javascript/DOC.md +1421 -0
- package/dist/microsoft/docs/onedrive/python/DOC.md +1549 -0
- package/dist/mongodb/docs/atlas/DOC.md +2041 -0
- package/dist/notion/docs/workspace-api/javascript/DOC.md +1435 -0
- package/dist/notion/docs/workspace-api/python/DOC.md +1400 -0
- package/dist/okta/docs/identity/javascript/DOC.md +1171 -0
- package/dist/okta/docs/identity/python/DOC.md +1401 -0
- package/dist/openai/docs/chat/javascript/DOC.md +407 -0
- package/dist/openai/docs/chat/python/DOC.md +568 -0
- package/dist/paypal/docs/checkout/DOC.md +278 -0
- package/dist/pinecone/docs/sdk/javascript/DOC.md +984 -0
- package/dist/pinecone/docs/sdk/python/DOC.md +1395 -0
- package/dist/plaid/docs/banking/javascript/DOC.md +1163 -0
- package/dist/plaid/docs/banking/python/DOC.md +1203 -0
- package/dist/playwright-community/skills/login-flows/SKILL.md +108 -0
- package/dist/postmark/docs/transactional-email/DOC.md +1168 -0
- package/dist/prisma/docs/orm/javascript/DOC.md +1419 -0
- package/dist/prisma/docs/orm/python/DOC.md +1317 -0
- package/dist/qdrant/docs/vector-search/javascript/DOC.md +1221 -0
- package/dist/qdrant/docs/vector-search/python/DOC.md +1653 -0
- package/dist/rabbitmq/docs/message-queue/javascript/DOC.md +1193 -0
- package/dist/rabbitmq/docs/message-queue/python/DOC.md +1243 -0
- package/dist/razorpay/docs/payments/javascript/DOC.md +1219 -0
- package/dist/razorpay/docs/payments/python/DOC.md +1330 -0
- package/dist/redis/docs/key-value/javascript/DOC.md +1851 -0
- package/dist/redis/docs/key-value/python/DOC.md +2054 -0
- package/dist/registry.json +2817 -0
- package/dist/replicate/docs/model-hosting/DOC.md +1318 -0
- package/dist/resend/docs/email/DOC.md +1271 -0
- package/dist/salesforce/docs/crm/javascript/DOC.md +1241 -0
- package/dist/salesforce/docs/crm/python/DOC.md +1183 -0
- package/dist/search-index.json +1 -0
- package/dist/sendgrid/docs/email-api/javascript/DOC.md +371 -0
- package/dist/sendgrid/docs/email-api/python/DOC.md +656 -0
- package/dist/sentry/docs/error-tracking/javascript/DOC.md +1073 -0
- package/dist/sentry/docs/error-tracking/python/DOC.md +1309 -0
- package/dist/shopify/docs/storefront/DOC.md +457 -0
- package/dist/slack/docs/workspace/javascript/DOC.md +933 -0
- package/dist/slack/docs/workspace/python/DOC.md +271 -0
- package/dist/square/docs/payments/javascript/DOC.md +1855 -0
- package/dist/square/docs/payments/python/DOC.md +1728 -0
- package/dist/stripe/docs/api/DOC.md +1727 -0
- package/dist/stripe/docs/payments/DOC.md +1726 -0
- package/dist/stytch/docs/auth/javascript/DOC.md +1813 -0
- package/dist/stytch/docs/auth/python/DOC.md +1962 -0
- package/dist/supabase/docs/client/DOC.md +1606 -0
- package/dist/twilio/docs/messaging/python/DOC.md +469 -0
- package/dist/twilio/docs/messaging/typescript/DOC.md +946 -0
- package/dist/vercel/docs/platform/DOC.md +1940 -0
- package/dist/weaviate/docs/vector-db/javascript/DOC.md +1268 -0
- package/dist/weaviate/docs/vector-db/python/DOC.md +1388 -0
- package/dist/zendesk/docs/support/javascript/DOC.md +2150 -0
- package/dist/zendesk/docs/support/python/DOC.md +2297 -0
- package/package.json +22 -6
- package/skills/get-api-docs/SKILL.md +84 -0
- package/src/commands/annotate.js +83 -0
- package/src/commands/build.js +12 -1
- package/src/commands/feedback.js +150 -0
- package/src/commands/get.js +83 -42
- package/src/commands/search.js +7 -0
- package/src/index.js +43 -17
- package/src/lib/analytics.js +90 -0
- package/src/lib/annotations.js +57 -0
- package/src/lib/bm25.js +170 -0
- package/src/lib/cache.js +69 -6
- package/src/lib/config.js +8 -3
- package/src/lib/identity.js +99 -0
- package/src/lib/registry.js +103 -20
- package/src/lib/telemetry.js +86 -0
- package/src/mcp/server.js +177 -0
- package/src/mcp/tools.js +251 -0
|
@@ -0,0 +1,1073 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: error-tracking
|
|
3
|
+
description: "Sentry JavaScript SDK for error tracking, performance monitoring, and distributed tracing in Node.js and browser applications."
|
|
4
|
+
metadata:
|
|
5
|
+
languages: "javascript"
|
|
6
|
+
versions: "10.23.0"
|
|
7
|
+
updated-on: "2026-03-01"
|
|
8
|
+
source: maintainer
|
|
9
|
+
tags: "sentry,monitoring,error-tracking,performance,tracing"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Sentry JavaScript SDK (10.23.0)
|
|
13
|
+
|
|
14
|
+
## Golden Rule
|
|
15
|
+
|
|
16
|
+
**ALWAYS use `@sentry/node` for Node.js applications or `@sentry/browser` for browser applications.**
|
|
17
|
+
|
|
18
|
+
The current stable version is **10.23.0**. Do not use deprecated packages like `raven` or `raven-js`.
|
|
19
|
+
|
|
20
|
+
For framework-specific applications, use the appropriate package:
|
|
21
|
+
- `@sentry/react` for React
|
|
22
|
+
- `@sentry/nextjs` for Next.js
|
|
23
|
+
- `@sentry/vue` for Vue
|
|
24
|
+
- `@sentry/angular` for Angular
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
### Node.js Applications
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install @sentry/node --save
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Browser Applications
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm install @sentry/browser --save
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Framework-Specific
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm install @sentry/react --save
|
|
44
|
+
npm install @sentry/nextjs --save
|
|
45
|
+
npm install @sentry/vue --save
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Environment Variables Setup
|
|
49
|
+
|
|
50
|
+
Create a `.env` file:
|
|
51
|
+
|
|
52
|
+
```env
|
|
53
|
+
SENTRY_DSN=https://examplePublicKey@o0.ingest.sentry.io/0
|
|
54
|
+
SENTRY_ENVIRONMENT=production
|
|
55
|
+
SENTRY_RELEASE=my-project@1.0.0
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Initialization
|
|
59
|
+
|
|
60
|
+
### Node.js Initialization
|
|
61
|
+
|
|
62
|
+
Create an `instrument.js` file and import it **before** any other modules:
|
|
63
|
+
|
|
64
|
+
```javascript
|
|
65
|
+
const Sentry = require("@sentry/node");
|
|
66
|
+
const { nodeProfilingIntegration } = require("@sentry/profiling-node");
|
|
67
|
+
|
|
68
|
+
Sentry.init({
|
|
69
|
+
dsn: process.env.SENTRY_DSN,
|
|
70
|
+
environment: process.env.SENTRY_ENVIRONMENT || "development",
|
|
71
|
+
release: process.env.SENTRY_RELEASE,
|
|
72
|
+
|
|
73
|
+
// Performance Monitoring
|
|
74
|
+
tracesSampleRate: 1.0, // Capture 100% of transactions for performance
|
|
75
|
+
|
|
76
|
+
// Profiling
|
|
77
|
+
integrations: [
|
|
78
|
+
nodeProfilingIntegration(),
|
|
79
|
+
],
|
|
80
|
+
profilesSampleRate: 1.0,
|
|
81
|
+
|
|
82
|
+
// Send user IP and cookies
|
|
83
|
+
sendDefaultPii: true,
|
|
84
|
+
|
|
85
|
+
// Enable logging to Sentry
|
|
86
|
+
enableLogs: true,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
module.exports = Sentry;
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Then import it first in your main file:
|
|
93
|
+
|
|
94
|
+
```javascript
|
|
95
|
+
require('./instrument');
|
|
96
|
+
|
|
97
|
+
const express = require('express');
|
|
98
|
+
const app = express();
|
|
99
|
+
|
|
100
|
+
// Your application code
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Browser Initialization
|
|
104
|
+
|
|
105
|
+
```javascript
|
|
106
|
+
import * as Sentry from "@sentry/browser";
|
|
107
|
+
|
|
108
|
+
Sentry.init({
|
|
109
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
110
|
+
|
|
111
|
+
// Environment and release tracking
|
|
112
|
+
environment: "production",
|
|
113
|
+
release: "my-project@2.3.12",
|
|
114
|
+
|
|
115
|
+
// Performance Monitoring
|
|
116
|
+
tracesSampleRate: 1.0,
|
|
117
|
+
integrations: [
|
|
118
|
+
Sentry.browserTracingIntegration(),
|
|
119
|
+
],
|
|
120
|
+
|
|
121
|
+
// Session Replay
|
|
122
|
+
replaysSessionSampleRate: 0.1, // 10% of sessions
|
|
123
|
+
replaysOnErrorSampleRate: 1.0, // 100% of sessions with errors
|
|
124
|
+
|
|
125
|
+
// Send user PII
|
|
126
|
+
sendDefaultPii: true,
|
|
127
|
+
});
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### React Initialization
|
|
131
|
+
|
|
132
|
+
```javascript
|
|
133
|
+
import React from "react";
|
|
134
|
+
import ReactDOM from "react-dom";
|
|
135
|
+
import * as Sentry from "@sentry/react";
|
|
136
|
+
import App from "./App";
|
|
137
|
+
|
|
138
|
+
Sentry.init({
|
|
139
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
140
|
+
integrations: [
|
|
141
|
+
Sentry.browserTracingIntegration(),
|
|
142
|
+
Sentry.replayIntegration(),
|
|
143
|
+
],
|
|
144
|
+
tracesSampleRate: 1.0,
|
|
145
|
+
replaysSessionSampleRate: 0.1,
|
|
146
|
+
replaysOnErrorSampleRate: 1.0,
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
ReactDOM.render(<App />, document.getElementById("root"));
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Error Tracking
|
|
153
|
+
|
|
154
|
+
### Capture Exceptions
|
|
155
|
+
|
|
156
|
+
**Automatic Error Capture:**
|
|
157
|
+
|
|
158
|
+
Sentry automatically captures unhandled exceptions and promise rejections.
|
|
159
|
+
|
|
160
|
+
```javascript
|
|
161
|
+
// This error will be automatically captured
|
|
162
|
+
throw new Error("Something went wrong!");
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**Manual Error Capture:**
|
|
166
|
+
|
|
167
|
+
```javascript
|
|
168
|
+
const Sentry = require("@sentry/node");
|
|
169
|
+
|
|
170
|
+
try {
|
|
171
|
+
someFailingFunction();
|
|
172
|
+
} catch (error) {
|
|
173
|
+
Sentry.captureException(error);
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**Capture with Context:**
|
|
178
|
+
|
|
179
|
+
```javascript
|
|
180
|
+
try {
|
|
181
|
+
processPayment(userId);
|
|
182
|
+
} catch (error) {
|
|
183
|
+
Sentry.withScope((scope) => {
|
|
184
|
+
scope.setTag("payment_method", "credit_card");
|
|
185
|
+
scope.setUser({ id: userId });
|
|
186
|
+
scope.setLevel("error");
|
|
187
|
+
Sentry.captureException(error);
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Capture Messages
|
|
193
|
+
|
|
194
|
+
```javascript
|
|
195
|
+
const Sentry = require("@sentry/node");
|
|
196
|
+
|
|
197
|
+
// Simple message
|
|
198
|
+
Sentry.captureMessage("User completed checkout");
|
|
199
|
+
|
|
200
|
+
// Message with severity level
|
|
201
|
+
Sentry.captureMessage("Payment processing slow", "warning");
|
|
202
|
+
|
|
203
|
+
// Available levels: "fatal", "error", "warning", "log", "info", "debug"
|
|
204
|
+
Sentry.captureMessage("Critical system failure", "fatal");
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Message with Context
|
|
208
|
+
|
|
209
|
+
```javascript
|
|
210
|
+
Sentry.withScope((scope) => {
|
|
211
|
+
scope.setTag("section", "checkout");
|
|
212
|
+
scope.setExtra("cart_total", 129.99);
|
|
213
|
+
Sentry.captureMessage("Checkout completed", "info");
|
|
214
|
+
});
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Enriching Error Data
|
|
218
|
+
|
|
219
|
+
### Set User Information
|
|
220
|
+
|
|
221
|
+
```javascript
|
|
222
|
+
Sentry.setUser({
|
|
223
|
+
id: "12345",
|
|
224
|
+
email: "user@example.com",
|
|
225
|
+
username: "john_doe",
|
|
226
|
+
ip_address: "{{auto}}", // Automatically capture IP
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// Clear user data
|
|
230
|
+
Sentry.setUser(null);
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Set Tags
|
|
234
|
+
|
|
235
|
+
Tags are searchable key-value pairs:
|
|
236
|
+
|
|
237
|
+
```javascript
|
|
238
|
+
// Set single tag
|
|
239
|
+
Sentry.setTag("page_locale", "en-us");
|
|
240
|
+
Sentry.setTag("environment", "staging");
|
|
241
|
+
|
|
242
|
+
// Set multiple tags
|
|
243
|
+
Sentry.setTags({
|
|
244
|
+
page_locale: "en-us",
|
|
245
|
+
user_type: "premium",
|
|
246
|
+
platform: "web",
|
|
247
|
+
});
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Set Context
|
|
251
|
+
|
|
252
|
+
Context adds structured data to events:
|
|
253
|
+
|
|
254
|
+
```javascript
|
|
255
|
+
Sentry.setContext("character", {
|
|
256
|
+
name: "Mighty Fighter",
|
|
257
|
+
age: 19,
|
|
258
|
+
attack_type: "melee",
|
|
259
|
+
level: 42,
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
Sentry.setContext("order", {
|
|
263
|
+
id: "ORD-12345",
|
|
264
|
+
total: 249.99,
|
|
265
|
+
items: 5,
|
|
266
|
+
shipping_method: "express",
|
|
267
|
+
});
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Set Extra Data
|
|
271
|
+
|
|
272
|
+
```javascript
|
|
273
|
+
Sentry.setExtra("debug_data", {
|
|
274
|
+
last_query: "SELECT * FROM users",
|
|
275
|
+
response_time: 1234,
|
|
276
|
+
});
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Add Breadcrumbs
|
|
280
|
+
|
|
281
|
+
Breadcrumbs create a trail of events leading to an error:
|
|
282
|
+
|
|
283
|
+
```javascript
|
|
284
|
+
import * as Sentry from "@sentry/browser";
|
|
285
|
+
|
|
286
|
+
// Manual breadcrumb
|
|
287
|
+
Sentry.addBreadcrumb({
|
|
288
|
+
category: "auth",
|
|
289
|
+
message: "User logged in",
|
|
290
|
+
level: "info",
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
Sentry.addBreadcrumb({
|
|
294
|
+
category: "api",
|
|
295
|
+
message: "API request to /users",
|
|
296
|
+
level: "info",
|
|
297
|
+
data: {
|
|
298
|
+
url: "/api/users",
|
|
299
|
+
method: "GET",
|
|
300
|
+
status_code: 200,
|
|
301
|
+
},
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
Sentry.addBreadcrumb({
|
|
305
|
+
category: "navigation",
|
|
306
|
+
message: "User navigated to checkout",
|
|
307
|
+
level: "info",
|
|
308
|
+
data: {
|
|
309
|
+
from: "/cart",
|
|
310
|
+
to: "/checkout",
|
|
311
|
+
},
|
|
312
|
+
});
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
**Automatic Breadcrumbs:**
|
|
316
|
+
|
|
317
|
+
The SDK automatically captures:
|
|
318
|
+
- DOM clicks and key presses
|
|
319
|
+
- XHR/fetch requests
|
|
320
|
+
- Console API calls
|
|
321
|
+
- Navigation/location changes
|
|
322
|
+
|
|
323
|
+
**Filter Breadcrumbs:**
|
|
324
|
+
|
|
325
|
+
```javascript
|
|
326
|
+
Sentry.init({
|
|
327
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
328
|
+
beforeBreadcrumb(breadcrumb, hint) {
|
|
329
|
+
// Filter out UI click events
|
|
330
|
+
if (breadcrumb.category === "ui.click") {
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Modify breadcrumb
|
|
335
|
+
if (breadcrumb.category === "console") {
|
|
336
|
+
breadcrumb.level = "debug";
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
return breadcrumb;
|
|
340
|
+
},
|
|
341
|
+
});
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
## Scopes
|
|
345
|
+
|
|
346
|
+
Scopes contain data that is attached to events.
|
|
347
|
+
|
|
348
|
+
### Global Scope
|
|
349
|
+
|
|
350
|
+
```javascript
|
|
351
|
+
// Set data on global scope (affects all events)
|
|
352
|
+
Sentry.getGlobalScope().setTag("app_version", "1.0.0");
|
|
353
|
+
Sentry.getGlobalScope().setExtras({
|
|
354
|
+
shared: "global",
|
|
355
|
+
global: "data",
|
|
356
|
+
});
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Isolation Scope
|
|
360
|
+
|
|
361
|
+
```javascript
|
|
362
|
+
// Set data on isolation scope (default scope for most operations)
|
|
363
|
+
Sentry.setTag("my-tag", "my value");
|
|
364
|
+
|
|
365
|
+
// Equivalent to:
|
|
366
|
+
Sentry.getIsolationScope().setTag("my-tag", "my value");
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### Current Scope
|
|
370
|
+
|
|
371
|
+
```javascript
|
|
372
|
+
// Set data on current scope
|
|
373
|
+
Sentry.getCurrentScope().setTag("request_id", "abc123");
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### Temporary Scope with withScope
|
|
377
|
+
|
|
378
|
+
```javascript
|
|
379
|
+
// Create temporary scope for specific error
|
|
380
|
+
Sentry.withScope((scope) => {
|
|
381
|
+
scope.setTag("section", "payment");
|
|
382
|
+
scope.setLevel("warning");
|
|
383
|
+
scope.setUser({ id: "12345" });
|
|
384
|
+
Sentry.captureException(new Error("Payment failed"));
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
// This error won't have the above tags
|
|
388
|
+
Sentry.captureException(new Error("Another error"));
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
**Multiple Scopes:**
|
|
392
|
+
|
|
393
|
+
```javascript
|
|
394
|
+
Sentry.withScope((scope) => {
|
|
395
|
+
scope.setTag("my-tag", "my value");
|
|
396
|
+
scope.setLevel("warning");
|
|
397
|
+
Sentry.captureException(new Error("my error")); // Has tag and level
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
Sentry.captureException(new Error("my other error")); // No tag or level
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### Scope Data Precedence
|
|
404
|
+
|
|
405
|
+
```javascript
|
|
406
|
+
// Global scope (lowest priority)
|
|
407
|
+
Sentry.getGlobalScope().setExtras({
|
|
408
|
+
shared: "global",
|
|
409
|
+
global: "data",
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
// Isolation scope (medium priority)
|
|
413
|
+
Sentry.getIsolationScope().setExtras({
|
|
414
|
+
shared: "isolation",
|
|
415
|
+
isolation: "data",
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
// Current scope (highest priority)
|
|
419
|
+
Sentry.getCurrentScope().setExtras({
|
|
420
|
+
shared: "current",
|
|
421
|
+
current: "data",
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
// Event will have: { shared: "current", global: "data", isolation: "data", current: "data" }
|
|
425
|
+
Sentry.captureException(new Error("my error"));
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
## Performance Monitoring
|
|
429
|
+
|
|
430
|
+
### Basic Transaction
|
|
431
|
+
|
|
432
|
+
```javascript
|
|
433
|
+
const Sentry = require("@sentry/node");
|
|
434
|
+
|
|
435
|
+
// Synchronous operation
|
|
436
|
+
const result = Sentry.startSpan(
|
|
437
|
+
{
|
|
438
|
+
name: "Process Order",
|
|
439
|
+
op: "task",
|
|
440
|
+
},
|
|
441
|
+
() => {
|
|
442
|
+
return processOrder();
|
|
443
|
+
}
|
|
444
|
+
);
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
### Async Transaction
|
|
448
|
+
|
|
449
|
+
```javascript
|
|
450
|
+
const result = await Sentry.startSpan(
|
|
451
|
+
{
|
|
452
|
+
name: "Fetch User Data",
|
|
453
|
+
op: "http.client",
|
|
454
|
+
},
|
|
455
|
+
async () => {
|
|
456
|
+
const response = await fetch("https://api.example.com/users");
|
|
457
|
+
const data = await response.json();
|
|
458
|
+
return data;
|
|
459
|
+
}
|
|
460
|
+
);
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### Nested Spans
|
|
464
|
+
|
|
465
|
+
```javascript
|
|
466
|
+
await Sentry.startSpan(
|
|
467
|
+
{
|
|
468
|
+
name: "Handle Request",
|
|
469
|
+
op: "http.server",
|
|
470
|
+
},
|
|
471
|
+
async () => {
|
|
472
|
+
// Child span 1
|
|
473
|
+
await Sentry.startSpan(
|
|
474
|
+
{
|
|
475
|
+
name: "Database Query",
|
|
476
|
+
op: "db.query",
|
|
477
|
+
},
|
|
478
|
+
async () => {
|
|
479
|
+
return await db.query("SELECT * FROM users");
|
|
480
|
+
}
|
|
481
|
+
);
|
|
482
|
+
|
|
483
|
+
// Child span 2
|
|
484
|
+
await Sentry.startSpan(
|
|
485
|
+
{
|
|
486
|
+
name: "Process Results",
|
|
487
|
+
op: "task",
|
|
488
|
+
},
|
|
489
|
+
async () => {
|
|
490
|
+
return await processResults();
|
|
491
|
+
}
|
|
492
|
+
);
|
|
493
|
+
}
|
|
494
|
+
);
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
### Manual Span Management
|
|
498
|
+
|
|
499
|
+
For cases where automatic span ending doesn't work:
|
|
500
|
+
|
|
501
|
+
```javascript
|
|
502
|
+
function middleware(_req, res, next) {
|
|
503
|
+
return Sentry.startSpanManual(
|
|
504
|
+
{
|
|
505
|
+
name: "middleware",
|
|
506
|
+
op: "middleware",
|
|
507
|
+
},
|
|
508
|
+
(span) => {
|
|
509
|
+
res.once("finish", () => {
|
|
510
|
+
span.setHttpStatus(res.status);
|
|
511
|
+
span.end();
|
|
512
|
+
});
|
|
513
|
+
return next();
|
|
514
|
+
}
|
|
515
|
+
);
|
|
516
|
+
}
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
### Add Span Attributes
|
|
520
|
+
|
|
521
|
+
```javascript
|
|
522
|
+
Sentry.startSpan(
|
|
523
|
+
{
|
|
524
|
+
name: "Process Payment",
|
|
525
|
+
op: "payment",
|
|
526
|
+
attributes: {
|
|
527
|
+
payment_method: "credit_card",
|
|
528
|
+
amount: 99.99,
|
|
529
|
+
currency: "USD",
|
|
530
|
+
user_id: "12345",
|
|
531
|
+
},
|
|
532
|
+
},
|
|
533
|
+
() => {
|
|
534
|
+
return processPayment();
|
|
535
|
+
}
|
|
536
|
+
);
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
### Span Operations
|
|
540
|
+
|
|
541
|
+
Use standard operation names:
|
|
542
|
+
|
|
543
|
+
```javascript
|
|
544
|
+
// HTTP requests
|
|
545
|
+
Sentry.startSpan({ name: "GET /api/users", op: "http.client" }, fetchUsers);
|
|
546
|
+
|
|
547
|
+
// Database queries
|
|
548
|
+
Sentry.startSpan({ name: "SELECT users", op: "db.query" }, queryUsers);
|
|
549
|
+
|
|
550
|
+
// Cache operations
|
|
551
|
+
Sentry.startSpan({ name: "Get from cache", op: "cache.get" }, getCache);
|
|
552
|
+
|
|
553
|
+
// File operations
|
|
554
|
+
Sentry.startSpan({ name: "Read file", op: "file.read" }, readFile);
|
|
555
|
+
|
|
556
|
+
// Custom tasks
|
|
557
|
+
Sentry.startSpan({ name: "Process data", op: "task" }, processData);
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
### Access Current Span
|
|
561
|
+
|
|
562
|
+
```javascript
|
|
563
|
+
const Sentry = require("@sentry/node");
|
|
564
|
+
|
|
565
|
+
function processItem(item) {
|
|
566
|
+
const span = Sentry.getActiveSpan();
|
|
567
|
+
|
|
568
|
+
if (span) {
|
|
569
|
+
span.setAttribute("item_id", item.id);
|
|
570
|
+
span.setAttribute("item_type", item.type);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
// Process item
|
|
574
|
+
}
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
### Express.js Integration
|
|
578
|
+
|
|
579
|
+
```javascript
|
|
580
|
+
const express = require("express");
|
|
581
|
+
const Sentry = require("./instrument");
|
|
582
|
+
|
|
583
|
+
const app = express();
|
|
584
|
+
|
|
585
|
+
// RequestHandler creates a separate execution context
|
|
586
|
+
app.use(Sentry.expressIntegration());
|
|
587
|
+
|
|
588
|
+
app.get("/", function rootHandler(req, res) {
|
|
589
|
+
res.end("Hello world!");
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
app.get("/debug-sentry", function mainHandler(req, res) {
|
|
593
|
+
throw new Error("My first Sentry error!");
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
// ErrorHandler must be registered before any other error middleware
|
|
597
|
+
app.use(Sentry.expressErrorHandler());
|
|
598
|
+
|
|
599
|
+
// Optional fallthrough error handler
|
|
600
|
+
app.use(function onError(err, req, res, next) {
|
|
601
|
+
res.statusCode = 500;
|
|
602
|
+
res.end(res.sentry + "\n");
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
app.listen(3000);
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
## Session Replay
|
|
609
|
+
|
|
610
|
+
Session Replay captures user interactions for debugging.
|
|
611
|
+
|
|
612
|
+
### Basic Session Replay Setup
|
|
613
|
+
|
|
614
|
+
```javascript
|
|
615
|
+
import * as Sentry from "@sentry/browser";
|
|
616
|
+
|
|
617
|
+
Sentry.init({
|
|
618
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
619
|
+
|
|
620
|
+
integrations: [
|
|
621
|
+
Sentry.replayIntegration({
|
|
622
|
+
maskAllText: true,
|
|
623
|
+
blockAllMedia: true,
|
|
624
|
+
}),
|
|
625
|
+
],
|
|
626
|
+
|
|
627
|
+
// Sample 10% of all sessions
|
|
628
|
+
replaysSessionSampleRate: 0.1,
|
|
629
|
+
|
|
630
|
+
// Sample 100% of sessions with errors
|
|
631
|
+
replaysOnErrorSampleRate: 1.0,
|
|
632
|
+
});
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
### Session Replay Configuration
|
|
636
|
+
|
|
637
|
+
```javascript
|
|
638
|
+
Sentry.init({
|
|
639
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
640
|
+
|
|
641
|
+
integrations: [
|
|
642
|
+
Sentry.replayIntegration({
|
|
643
|
+
// Privacy settings
|
|
644
|
+
maskAllText: true,
|
|
645
|
+
maskAllInputs: true,
|
|
646
|
+
blockAllMedia: true,
|
|
647
|
+
|
|
648
|
+
// Network details
|
|
649
|
+
networkDetailAllowUrls: ["https://api.example.com"],
|
|
650
|
+
networkRequestHeaders: ["X-Custom-Header"],
|
|
651
|
+
networkResponseHeaders: ["X-Custom-Header"],
|
|
652
|
+
|
|
653
|
+
// Performance
|
|
654
|
+
networkCaptureBodies: true,
|
|
655
|
+
|
|
656
|
+
// Canvas recording (experimental)
|
|
657
|
+
// Note: No PII scrubbing for canvas!
|
|
658
|
+
}),
|
|
659
|
+
|
|
660
|
+
// Optional: Canvas recording
|
|
661
|
+
Sentry.replayCanvasIntegration(),
|
|
662
|
+
],
|
|
663
|
+
|
|
664
|
+
replaysSessionSampleRate: 0.1,
|
|
665
|
+
replaysOnErrorSampleRate: 1.0,
|
|
666
|
+
});
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
### Lazy-Load Session Replay
|
|
670
|
+
|
|
671
|
+
```javascript
|
|
672
|
+
Sentry.init({
|
|
673
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
674
|
+
integrations: [],
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
// Load replay later (e.g., after user interaction)
|
|
678
|
+
import("@sentry/browser").then((lazyLoadedSentry) => {
|
|
679
|
+
Sentry.addIntegration(
|
|
680
|
+
lazyLoadedSentry.replayIntegration({
|
|
681
|
+
maskAllText: true,
|
|
682
|
+
blockAllMedia: true,
|
|
683
|
+
})
|
|
684
|
+
);
|
|
685
|
+
});
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
## Source Maps
|
|
689
|
+
|
|
690
|
+
Upload source maps to see readable stack traces:
|
|
691
|
+
|
|
692
|
+
### Install Sentry CLI
|
|
693
|
+
|
|
694
|
+
```bash
|
|
695
|
+
npm install @sentry/cli --save-dev
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
### Configure Source Maps Upload
|
|
699
|
+
|
|
700
|
+
Create `.sentryclirc`:
|
|
701
|
+
|
|
702
|
+
```ini
|
|
703
|
+
[auth]
|
|
704
|
+
token=YOUR_AUTH_TOKEN
|
|
705
|
+
|
|
706
|
+
[defaults]
|
|
707
|
+
url=https://sentry.io/
|
|
708
|
+
org=your-organization
|
|
709
|
+
project=your-project
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
### Upload with Webpack
|
|
713
|
+
|
|
714
|
+
```javascript
|
|
715
|
+
const SentryWebpackPlugin = require("@sentry/webpack-plugin");
|
|
716
|
+
|
|
717
|
+
module.exports = {
|
|
718
|
+
// ... other webpack config
|
|
719
|
+
|
|
720
|
+
plugins: [
|
|
721
|
+
new SentryWebpackPlugin({
|
|
722
|
+
authToken: process.env.SENTRY_AUTH_TOKEN,
|
|
723
|
+
org: "your-organization",
|
|
724
|
+
project: "your-project",
|
|
725
|
+
include: "./dist",
|
|
726
|
+
ignore: ["node_modules", "webpack.config.js"],
|
|
727
|
+
}),
|
|
728
|
+
],
|
|
729
|
+
};
|
|
730
|
+
```
|
|
731
|
+
|
|
732
|
+
### Manual Upload
|
|
733
|
+
|
|
734
|
+
```bash
|
|
735
|
+
sentry-cli releases files VERSION upload-sourcemaps /path/to/files
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
## Event Filtering
|
|
739
|
+
|
|
740
|
+
### Before Send Hook
|
|
741
|
+
|
|
742
|
+
```javascript
|
|
743
|
+
Sentry.init({
|
|
744
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
745
|
+
|
|
746
|
+
beforeSend(event, hint) {
|
|
747
|
+
// Don't send events in development
|
|
748
|
+
if (process.env.NODE_ENV === "development") {
|
|
749
|
+
return null;
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
// Filter out specific errors
|
|
753
|
+
if (event.exception) {
|
|
754
|
+
const error = hint.originalException;
|
|
755
|
+
if (error && error.message && error.message.match(/network error/i)) {
|
|
756
|
+
return null;
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
// Modify event
|
|
761
|
+
if (event.user) {
|
|
762
|
+
delete event.user.ip_address;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
return event;
|
|
766
|
+
},
|
|
767
|
+
});
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
### Before Send Transaction Hook
|
|
771
|
+
|
|
772
|
+
```javascript
|
|
773
|
+
Sentry.init({
|
|
774
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
775
|
+
tracesSampleRate: 1.0,
|
|
776
|
+
|
|
777
|
+
beforeSendTransaction(event, hint) {
|
|
778
|
+
// Don't send health check transactions
|
|
779
|
+
if (event.transaction === "GET /health") {
|
|
780
|
+
return null;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
// Add custom data to all spans
|
|
784
|
+
if (event.spans) {
|
|
785
|
+
event.spans.forEach((span) => {
|
|
786
|
+
span.data = span.data || {};
|
|
787
|
+
span.data.custom_field = "custom_value";
|
|
788
|
+
});
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
return event;
|
|
792
|
+
},
|
|
793
|
+
});
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
## Sampling
|
|
797
|
+
|
|
798
|
+
### Error Sampling
|
|
799
|
+
|
|
800
|
+
```javascript
|
|
801
|
+
Sentry.init({
|
|
802
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
803
|
+
|
|
804
|
+
// Sample 50% of errors
|
|
805
|
+
sampleRate: 0.5,
|
|
806
|
+
});
|
|
807
|
+
```
|
|
808
|
+
|
|
809
|
+
### Performance Sampling
|
|
810
|
+
|
|
811
|
+
```javascript
|
|
812
|
+
Sentry.init({
|
|
813
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
814
|
+
|
|
815
|
+
// Sample 25% of transactions
|
|
816
|
+
tracesSampleRate: 0.25,
|
|
817
|
+
|
|
818
|
+
// Or use dynamic sampling
|
|
819
|
+
tracesSampler(samplingContext) {
|
|
820
|
+
// Sample critical paths at 100%
|
|
821
|
+
if (samplingContext.transactionContext.name.includes("/checkout")) {
|
|
822
|
+
return 1.0;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
// Sample health checks at 10%
|
|
826
|
+
if (samplingContext.transactionContext.name.includes("/health")) {
|
|
827
|
+
return 0.1;
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
// Default to 25%
|
|
831
|
+
return 0.25;
|
|
832
|
+
},
|
|
833
|
+
});
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
### Profile Sampling
|
|
837
|
+
|
|
838
|
+
```javascript
|
|
839
|
+
Sentry.init({
|
|
840
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
841
|
+
|
|
842
|
+
integrations: [nodeProfilingIntegration()],
|
|
843
|
+
|
|
844
|
+
// Profile 10% of transactions
|
|
845
|
+
profilesSampleRate: 0.1,
|
|
846
|
+
});
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
## Releases and Deploys
|
|
850
|
+
|
|
851
|
+
### Set Release
|
|
852
|
+
|
|
853
|
+
```javascript
|
|
854
|
+
Sentry.init({
|
|
855
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
856
|
+
release: "my-project@1.2.3",
|
|
857
|
+
environment: "production",
|
|
858
|
+
});
|
|
859
|
+
```
|
|
860
|
+
|
|
861
|
+
### Create Release with CLI
|
|
862
|
+
|
|
863
|
+
```bash
|
|
864
|
+
# Create release
|
|
865
|
+
sentry-cli releases new my-project@1.2.3
|
|
866
|
+
|
|
867
|
+
# Associate commits
|
|
868
|
+
sentry-cli releases set-commits my-project@1.2.3 --auto
|
|
869
|
+
|
|
870
|
+
# Finalize release
|
|
871
|
+
sentry-cli releases finalize my-project@1.2.3
|
|
872
|
+
|
|
873
|
+
# Create deploy
|
|
874
|
+
sentry-cli releases deploys my-project@1.2.3 new -e production
|
|
875
|
+
```
|
|
876
|
+
|
|
877
|
+
## Testing Sentry Setup
|
|
878
|
+
|
|
879
|
+
### Test Error
|
|
880
|
+
|
|
881
|
+
```javascript
|
|
882
|
+
setTimeout(() => {
|
|
883
|
+
throw new Error("Sentry Test Error - This is intentional!");
|
|
884
|
+
}, 1000);
|
|
885
|
+
```
|
|
886
|
+
|
|
887
|
+
### Test Message
|
|
888
|
+
|
|
889
|
+
```javascript
|
|
890
|
+
Sentry.captureMessage("Sentry is configured correctly!", "info");
|
|
891
|
+
```
|
|
892
|
+
|
|
893
|
+
### Test Transaction
|
|
894
|
+
|
|
895
|
+
```javascript
|
|
896
|
+
Sentry.startSpan(
|
|
897
|
+
{
|
|
898
|
+
name: "Test Transaction",
|
|
899
|
+
op: "test",
|
|
900
|
+
},
|
|
901
|
+
() => {
|
|
902
|
+
console.log("Testing Sentry performance monitoring");
|
|
903
|
+
}
|
|
904
|
+
);
|
|
905
|
+
```
|
|
906
|
+
|
|
907
|
+
## Browser Integrations
|
|
908
|
+
|
|
909
|
+
### Breadcrumbs Integration
|
|
910
|
+
|
|
911
|
+
```javascript
|
|
912
|
+
Sentry.init({
|
|
913
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
914
|
+
integrations: [
|
|
915
|
+
Sentry.breadcrumbsIntegration({
|
|
916
|
+
console: true, // Console logs
|
|
917
|
+
dom: true, // DOM events
|
|
918
|
+
fetch: true, // Fetch requests
|
|
919
|
+
history: true, // Navigation
|
|
920
|
+
xhr: true, // XHR requests
|
|
921
|
+
}),
|
|
922
|
+
],
|
|
923
|
+
});
|
|
924
|
+
```
|
|
925
|
+
|
|
926
|
+
### HTTP Client Integration
|
|
927
|
+
|
|
928
|
+
```javascript
|
|
929
|
+
Sentry.init({
|
|
930
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
931
|
+
integrations: [
|
|
932
|
+
Sentry.httpClientIntegration({
|
|
933
|
+
failedRequestStatusCodes: [[400, 599]],
|
|
934
|
+
failedRequestTargets: ["https://api.example.com"],
|
|
935
|
+
}),
|
|
936
|
+
],
|
|
937
|
+
});
|
|
938
|
+
```
|
|
939
|
+
|
|
940
|
+
### Context Lines Integration
|
|
941
|
+
|
|
942
|
+
```javascript
|
|
943
|
+
Sentry.init({
|
|
944
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
945
|
+
integrations: [
|
|
946
|
+
Sentry.contextLinesIntegration({
|
|
947
|
+
frameContextLines: 5,
|
|
948
|
+
}),
|
|
949
|
+
],
|
|
950
|
+
});
|
|
951
|
+
```
|
|
952
|
+
|
|
953
|
+
## Advanced Configuration
|
|
954
|
+
|
|
955
|
+
### Multiple Sentry Instances
|
|
956
|
+
|
|
957
|
+
```javascript
|
|
958
|
+
const Sentry = require("@sentry/node");
|
|
959
|
+
|
|
960
|
+
// Create hub for primary app
|
|
961
|
+
const primaryHub = new Sentry.Hub(new Sentry.Client({
|
|
962
|
+
dsn: "https://primary@sentry.io/0",
|
|
963
|
+
}));
|
|
964
|
+
|
|
965
|
+
// Create hub for background jobs
|
|
966
|
+
const jobsHub = new Sentry.Hub(new Sentry.Client({
|
|
967
|
+
dsn: "https://jobs@sentry.io/1",
|
|
968
|
+
}));
|
|
969
|
+
|
|
970
|
+
// Use specific hub
|
|
971
|
+
primaryHub.withScope((scope) => {
|
|
972
|
+
primaryHub.captureException(new Error("Primary app error"));
|
|
973
|
+
});
|
|
974
|
+
|
|
975
|
+
jobsHub.withScope((scope) => {
|
|
976
|
+
jobsHub.captureException(new Error("Background job error"));
|
|
977
|
+
});
|
|
978
|
+
```
|
|
979
|
+
|
|
980
|
+
### Custom Transport
|
|
981
|
+
|
|
982
|
+
```javascript
|
|
983
|
+
Sentry.init({
|
|
984
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
985
|
+
transport: Sentry.makeNodeTransport,
|
|
986
|
+
transportOptions: {
|
|
987
|
+
headers: {
|
|
988
|
+
"X-Custom-Header": "custom-value",
|
|
989
|
+
},
|
|
990
|
+
},
|
|
991
|
+
});
|
|
992
|
+
```
|
|
993
|
+
|
|
994
|
+
### Debug Mode
|
|
995
|
+
|
|
996
|
+
```javascript
|
|
997
|
+
Sentry.init({
|
|
998
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
999
|
+
debug: true, // Enable debug logging
|
|
1000
|
+
});
|
|
1001
|
+
```
|
|
1002
|
+
|
|
1003
|
+
### Maximum Breadcrumbs
|
|
1004
|
+
|
|
1005
|
+
```javascript
|
|
1006
|
+
Sentry.init({
|
|
1007
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
1008
|
+
maxBreadcrumbs: 50, // Default is 100
|
|
1009
|
+
});
|
|
1010
|
+
```
|
|
1011
|
+
|
|
1012
|
+
### Shutdown
|
|
1013
|
+
|
|
1014
|
+
```javascript
|
|
1015
|
+
// Flush events and close transport
|
|
1016
|
+
await Sentry.close(2000); // Wait up to 2 seconds
|
|
1017
|
+
|
|
1018
|
+
// Or just flush without closing
|
|
1019
|
+
await Sentry.flush(2000);
|
|
1020
|
+
```
|
|
1021
|
+
|
|
1022
|
+
## Node.js Integrations
|
|
1023
|
+
|
|
1024
|
+
### HTTP Integration
|
|
1025
|
+
|
|
1026
|
+
```javascript
|
|
1027
|
+
const Sentry = require("@sentry/node");
|
|
1028
|
+
|
|
1029
|
+
Sentry.init({
|
|
1030
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
1031
|
+
integrations: [
|
|
1032
|
+
Sentry.httpIntegration({
|
|
1033
|
+
tracing: true,
|
|
1034
|
+
breadcrumbs: true,
|
|
1035
|
+
}),
|
|
1036
|
+
],
|
|
1037
|
+
});
|
|
1038
|
+
```
|
|
1039
|
+
|
|
1040
|
+
### Console Integration
|
|
1041
|
+
|
|
1042
|
+
```javascript
|
|
1043
|
+
Sentry.init({
|
|
1044
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
1045
|
+
integrations: [
|
|
1046
|
+
Sentry.consoleIntegration({
|
|
1047
|
+
levels: ["error", "warn"],
|
|
1048
|
+
}),
|
|
1049
|
+
],
|
|
1050
|
+
});
|
|
1051
|
+
```
|
|
1052
|
+
|
|
1053
|
+
### Modules Integration
|
|
1054
|
+
|
|
1055
|
+
```javascript
|
|
1056
|
+
Sentry.init({
|
|
1057
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
1058
|
+
integrations: [
|
|
1059
|
+
Sentry.modulesIntegration(),
|
|
1060
|
+
],
|
|
1061
|
+
});
|
|
1062
|
+
```
|
|
1063
|
+
|
|
1064
|
+
### Context Integration
|
|
1065
|
+
|
|
1066
|
+
```javascript
|
|
1067
|
+
Sentry.init({
|
|
1068
|
+
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
|
|
1069
|
+
integrations: [
|
|
1070
|
+
Sentry.contextIntegration(),
|
|
1071
|
+
],
|
|
1072
|
+
});
|
|
1073
|
+
```
|