@watchforge/browser 0.1.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/CONFIGURATION_GUIDE.md +755 -0
- package/LICENSE +201 -0
- package/README.md +142 -0
- package/package.json +58 -0
- package/src/client.js +628 -0
- package/src/express.js +77 -0
- package/src/index.js +12 -0
- package/src/react.js +46 -0
- package/src/tracing.js +253 -0
- package/src/transport.js +191 -0
|
@@ -0,0 +1,755 @@
|
|
|
1
|
+
# WatchForge JavaScript SDK - Configuration Guide
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The WatchForge JavaScript SDK automatically captures errors and events in:
|
|
6
|
+
- **Node.js** applications
|
|
7
|
+
- **Express.js** web servers
|
|
8
|
+
- **React** frontend applications
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
### From npm (when published)
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install @watchforge/browser
|
|
16
|
+
# or
|
|
17
|
+
yarn add @watchforge/browser
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### From Local Directory (for development/testing)
|
|
21
|
+
|
|
22
|
+
If you want to install the SDK directly from your local directory:
|
|
23
|
+
|
|
24
|
+
**Option 1: Install from local path**
|
|
25
|
+
```bash
|
|
26
|
+
# In your project directory
|
|
27
|
+
npm install /path/to/watchforge-javascript-sdk
|
|
28
|
+
# or with relative path
|
|
29
|
+
npm install ../watchforge-javascript-sdk
|
|
30
|
+
# or
|
|
31
|
+
yarn add /path/to/watchforge-javascript-sdk
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Option 2: Use npm link (recommended for development)**
|
|
35
|
+
```bash
|
|
36
|
+
# Step 1: In watchforge-javascript-sdk directory
|
|
37
|
+
cd watchforge-javascript-sdk
|
|
38
|
+
npm link
|
|
39
|
+
|
|
40
|
+
# Step 2: In your project directory
|
|
41
|
+
cd /path/to/your-project
|
|
42
|
+
npm link @watchforge/browser
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Option 3: Install from local directory with file: protocol**
|
|
46
|
+
```bash
|
|
47
|
+
# In your project directory
|
|
48
|
+
npm install file:../watchforge-javascript-sdk
|
|
49
|
+
# or
|
|
50
|
+
yarn add file:../watchforge-javascript-sdk
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Example:**
|
|
54
|
+
```bash
|
|
55
|
+
# If your project structure is:
|
|
56
|
+
# /Users/shubhampatel/Documents/
|
|
57
|
+
# ├── test-example/
|
|
58
|
+
# │ ├── watchforge-javascript-sdk/
|
|
59
|
+
# │ └── my-react-app/
|
|
60
|
+
|
|
61
|
+
# From my-react-app directory:
|
|
62
|
+
cd my-react-app
|
|
63
|
+
npm install ../watchforge-javascript-sdk
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
After installation, use it the same way:
|
|
67
|
+
```javascript
|
|
68
|
+
import { register, ErrorBoundary } from '@watchforge/browser';
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Quick Testing
|
|
72
|
+
|
|
73
|
+
### Prerequisites
|
|
74
|
+
|
|
75
|
+
1. **Make sure your backend is running:**
|
|
76
|
+
```bash
|
|
77
|
+
cd watchforge-backend
|
|
78
|
+
python manage.py runserver 8001
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
2. **Navigate to SDK directory:**
|
|
82
|
+
```bash
|
|
83
|
+
cd watchforge-javascript-sdk
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Test Node.js SDK
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# Run the test script
|
|
90
|
+
node test-node.js
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
This will:
|
|
94
|
+
- ✅ Initialize the SDK
|
|
95
|
+
- ✅ Capture a test exception
|
|
96
|
+
- ✅ Capture exception with user context
|
|
97
|
+
- ✅ Send test messages
|
|
98
|
+
- ✅ Trigger unhandled exceptions/rejections (auto-captured)
|
|
99
|
+
|
|
100
|
+
**Expected Output:**
|
|
101
|
+
```
|
|
102
|
+
✅ WatchForge SDK initialized for Node.js
|
|
103
|
+
📝 Test 1: Capturing exception...
|
|
104
|
+
✅ Exception captured
|
|
105
|
+
...
|
|
106
|
+
✅ Test complete!
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Test Express.js SDK
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# Step 1: Install Express (first time only)
|
|
113
|
+
npm install express
|
|
114
|
+
|
|
115
|
+
# Step 2: Run the test server
|
|
116
|
+
node test-express.js
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Expected Output:**
|
|
120
|
+
```
|
|
121
|
+
✅ WatchForge SDK initialized for Express.js
|
|
122
|
+
🚀 Express server running on http://localhost:3000
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Step 3: Test endpoints:**
|
|
126
|
+
```bash
|
|
127
|
+
# Visit in browser or use curl:
|
|
128
|
+
curl http://localhost:3000/ok # Works fine
|
|
129
|
+
curl http://localhost:3000/error # Triggers error (check backend logs)
|
|
130
|
+
curl http://localhost:3000/async-error # Triggers async error
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Test React SDK
|
|
134
|
+
|
|
135
|
+
**Note:** `test-react.html` is a demonstration file. In a real React app:
|
|
136
|
+
|
|
137
|
+
1. **Install the SDK:**
|
|
138
|
+
```bash
|
|
139
|
+
npm install @watchforge/browser
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
2. **Use in your React app:**
|
|
143
|
+
```javascript
|
|
144
|
+
import { register, ErrorBoundary } from '@watchforge/browser';
|
|
145
|
+
|
|
146
|
+
register({
|
|
147
|
+
dsn: "https://PUBLIC_KEY@watchforge.io/PROJECT_ID",
|
|
148
|
+
app_env: "production",
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// Wrap your app
|
|
152
|
+
<ErrorBoundary>
|
|
153
|
+
<App />
|
|
154
|
+
</ErrorBoundary>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
See the React setup section below for complete examples.
|
|
158
|
+
|
|
159
|
+
## Quick Start
|
|
160
|
+
|
|
161
|
+
### 1. Node.js Application
|
|
162
|
+
|
|
163
|
+
```javascript
|
|
164
|
+
// app.js
|
|
165
|
+
const { register, captureException, captureMessage } = require('@watchforge/browser');
|
|
166
|
+
|
|
167
|
+
// Initialize SDK
|
|
168
|
+
// API URL is automatically derived from DSN host
|
|
169
|
+
register({
|
|
170
|
+
dsn: "https://PUBLIC_KEY@watchforge.io/PROJECT_ID",
|
|
171
|
+
app_env: "production",
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
// Your application code
|
|
175
|
+
try {
|
|
176
|
+
// some code that might fail
|
|
177
|
+
} catch (error) {
|
|
178
|
+
captureException(error); // ✅ Automatically sent to backend
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Log messages
|
|
182
|
+
captureMessage("User logged in", "info");
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### 2. Express.js Application
|
|
186
|
+
|
|
187
|
+
```javascript
|
|
188
|
+
// server.js
|
|
189
|
+
const express = require('express');
|
|
190
|
+
const { register, expressMiddleware } = require('@watchforge/browser');
|
|
191
|
+
|
|
192
|
+
const app = express();
|
|
193
|
+
|
|
194
|
+
// Initialize SDK
|
|
195
|
+
// API URL is automatically derived from DSN host
|
|
196
|
+
register({
|
|
197
|
+
dsn: "https://PUBLIC_KEY@watchforge.io/PROJECT_ID",
|
|
198
|
+
app_env: "production",
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
// Use Express error handler middleware (automatically captures errors with context)
|
|
202
|
+
app.use(expressMiddleware());
|
|
203
|
+
|
|
204
|
+
// Your routes
|
|
205
|
+
app.get('/api/users', (req, res) => {
|
|
206
|
+
// If error occurs, it's automatically captured with request context
|
|
207
|
+
res.json({ users: [] });
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
app.listen(3000);
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### 3. React Application
|
|
214
|
+
|
|
215
|
+
```javascript
|
|
216
|
+
// src/index.js or App.js
|
|
217
|
+
import { register, ErrorBoundary } from '@watchforge/browser';
|
|
218
|
+
|
|
219
|
+
// Initialize SDK
|
|
220
|
+
// API URL is automatically derived from DSN host
|
|
221
|
+
register({
|
|
222
|
+
dsn: "https://PUBLIC_KEY@watchforge.io/PROJECT_ID",
|
|
223
|
+
app_env: "production",
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// Wrap your app with ErrorBoundary
|
|
227
|
+
function App() {
|
|
228
|
+
return (
|
|
229
|
+
<ErrorBoundary>
|
|
230
|
+
<YourApp />
|
|
231
|
+
</ErrorBoundary>
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## API Reference
|
|
237
|
+
|
|
238
|
+
### `register(options)`
|
|
239
|
+
|
|
240
|
+
Initialize the WatchForge SDK.
|
|
241
|
+
|
|
242
|
+
**Options:**
|
|
243
|
+
- `dsn` (string, required): Your project DSN. API URL is automatically derived from the DSN host.
|
|
244
|
+
- `app_env` (string, default: "production"): Application environment name
|
|
245
|
+
- `release` (string, optional): Release version identifier (e.g., "my-app@1.2.3" or "bustto-main-domain@9.6.5")
|
|
246
|
+
- `debug` (boolean, default: false): Enable debug logging
|
|
247
|
+
|
|
248
|
+
**Example:**
|
|
249
|
+
```javascript
|
|
250
|
+
register({
|
|
251
|
+
dsn: "https://PUBLIC_KEY@watchforge.io/PROJECT_ID",
|
|
252
|
+
app_env: "production",
|
|
253
|
+
release: "my-app@1.2.3", // Optional: Track which version caused errors
|
|
254
|
+
debug: true, // Enable debug logging
|
|
255
|
+
});
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
**Release Parameter:**
|
|
259
|
+
The `release` parameter helps you:
|
|
260
|
+
- Track which version of your app caused errors
|
|
261
|
+
- Filter errors by release version
|
|
262
|
+
- Make rollback decisions based on error rates
|
|
263
|
+
- Correlate errors with specific deployments
|
|
264
|
+
|
|
265
|
+
**Example release formats:**
|
|
266
|
+
- `"my-app@1.2.3"` - Semantic versioning
|
|
267
|
+
- `"bustto-main-domain@9.6.5"` - Domain and version
|
|
268
|
+
- `"v1.2.3"` - Simple version tag
|
|
269
|
+
- `"2024-01-15-release"` - Date-based release
|
|
270
|
+
|
|
271
|
+
**Note:** The API URL is automatically derived from the DSN host. For local development:
|
|
272
|
+
- Use a DSN with `localhost` or `127.0.0.1`: `https://PUBLIC_KEY@127.0.0.1:8001/PROJECT_ID`
|
|
273
|
+
- Or set `WATCHFORGE_API_URL` environment variable to override
|
|
274
|
+
|
|
275
|
+
**Note:** `init()` is deprecated. Use `register()` instead for consistency with the Python SDK.
|
|
276
|
+
|
|
277
|
+
### `captureException(error, context)`
|
|
278
|
+
|
|
279
|
+
Capture an exception with optional context.
|
|
280
|
+
|
|
281
|
+
**Parameters:**
|
|
282
|
+
- `error` (Error): The error/exception to capture
|
|
283
|
+
- `context` (object, optional): Additional context
|
|
284
|
+
- `user` (object): User information
|
|
285
|
+
- `request` (object): Request information
|
|
286
|
+
- `tags` (object): Tags for filtering
|
|
287
|
+
- `extra` (object): Extra data
|
|
288
|
+
|
|
289
|
+
**Example:**
|
|
290
|
+
```javascript
|
|
291
|
+
try {
|
|
292
|
+
// your code
|
|
293
|
+
} catch (error) {
|
|
294
|
+
captureException(error, {
|
|
295
|
+
user: {
|
|
296
|
+
id: "123",
|
|
297
|
+
email: "user@example.com",
|
|
298
|
+
ip_address: "192.168.1.1",
|
|
299
|
+
},
|
|
300
|
+
request: {
|
|
301
|
+
url: "/api/users",
|
|
302
|
+
method: "GET",
|
|
303
|
+
},
|
|
304
|
+
tags: {
|
|
305
|
+
component: "user-service",
|
|
306
|
+
},
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### `captureMessage(message, level, context)`
|
|
312
|
+
|
|
313
|
+
Capture a custom message.
|
|
314
|
+
|
|
315
|
+
**Parameters:**
|
|
316
|
+
- `message` (string): Message to capture
|
|
317
|
+
- `level` (string, default: "info"): Level (info, warning, error)
|
|
318
|
+
- `context` (object, optional): Additional context
|
|
319
|
+
|
|
320
|
+
**Example:**
|
|
321
|
+
```javascript
|
|
322
|
+
captureMessage("User logged in", "info", {
|
|
323
|
+
user: { id: "123", email: "user@example.com" },
|
|
324
|
+
});
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
## Framework-Specific Examples
|
|
328
|
+
|
|
329
|
+
### Express.js - Complete Setup
|
|
330
|
+
|
|
331
|
+
```javascript
|
|
332
|
+
// server.js
|
|
333
|
+
const express = require('express');
|
|
334
|
+
const { register, expressMiddleware } = require('@watchforge/browser');
|
|
335
|
+
|
|
336
|
+
const app = express();
|
|
337
|
+
|
|
338
|
+
// Initialize SDK
|
|
339
|
+
// API URL is automatically derived from DSN host
|
|
340
|
+
// Set WATCHFORGE_API_URL env var to override for local dev
|
|
341
|
+
register({
|
|
342
|
+
dsn: process.env.WATCHFORGE_DSN,
|
|
343
|
+
app_env: process.env.NODE_ENV || "production",
|
|
344
|
+
debug: process.env.NODE_ENV === 'development',
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
// Use Express error handler middleware
|
|
348
|
+
// This automatically captures errors with request context, user info, and IP address
|
|
349
|
+
app.use(expressMiddleware());
|
|
350
|
+
|
|
351
|
+
// Your routes
|
|
352
|
+
app.get('/api/users', (req, res) => {
|
|
353
|
+
res.json({ users: [] });
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
app.listen(3000);
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### React - Complete Setup
|
|
360
|
+
|
|
361
|
+
```javascript
|
|
362
|
+
// src/index.js
|
|
363
|
+
import React from 'react';
|
|
364
|
+
import ReactDOM from 'react-dom';
|
|
365
|
+
import { register, ErrorBoundary } from '@watchforge/browser';
|
|
366
|
+
import App from './App';
|
|
367
|
+
|
|
368
|
+
// Initialize SDK
|
|
369
|
+
// API URL is automatically derived from DSN host
|
|
370
|
+
register({
|
|
371
|
+
dsn: process.env.REACT_APP_WATCHFORGE_DSN,
|
|
372
|
+
app_env: process.env.NODE_ENV || "production",
|
|
373
|
+
debug: process.env.NODE_ENV === 'development',
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
// ✅ Automatically captured (NO ErrorBoundary needed):
|
|
377
|
+
// - window.onerror (uncaught JavaScript errors)
|
|
378
|
+
// - window.onunhandledrejection (unhandled promise rejections)
|
|
379
|
+
// - Errors in event handlers
|
|
380
|
+
// - Errors in async code
|
|
381
|
+
|
|
382
|
+
// ⚠️ ErrorBoundary needed for:
|
|
383
|
+
// - React component render errors
|
|
384
|
+
// - React lifecycle method errors
|
|
385
|
+
// - React constructor errors
|
|
386
|
+
|
|
387
|
+
// Recommended: Wrap your app with ErrorBoundary to catch React component errors
|
|
388
|
+
ReactDOM.render(
|
|
389
|
+
<ErrorBoundary>
|
|
390
|
+
<App />
|
|
391
|
+
</ErrorBoundary>,
|
|
392
|
+
document.getElementById('root')
|
|
393
|
+
);
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
**Is ErrorBoundary compulsory?**
|
|
397
|
+
|
|
398
|
+
**No, but recommended:**
|
|
399
|
+
- ✅ **General JavaScript errors** are automatically captured (no ErrorBoundary needed)
|
|
400
|
+
- ✅ **Unhandled promise rejections** are automatically captured
|
|
401
|
+
- ✅ **Event handler errors** are automatically captured
|
|
402
|
+
- ⚠️ **React component errors** require ErrorBoundary (React requirement)
|
|
403
|
+
|
|
404
|
+
**Minimal setup (without ErrorBoundary):**
|
|
405
|
+
```javascript
|
|
406
|
+
// This will still capture most errors automatically
|
|
407
|
+
register({
|
|
408
|
+
dsn: "...",
|
|
409
|
+
app_env: "production",
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
ReactDOM.render(<App />, document.getElementById('root'));
|
|
413
|
+
// ✅ JavaScript errors, promise rejections, etc. are auto-captured
|
|
414
|
+
// ❌ React component render errors won't be captured
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
**Recommended setup (with ErrorBoundary):**
|
|
418
|
+
```javascript
|
|
419
|
+
register({
|
|
420
|
+
dsn: "...",
|
|
421
|
+
app_env: "production",
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
ReactDOM.render(
|
|
425
|
+
<ErrorBoundary>
|
|
426
|
+
<App />
|
|
427
|
+
</ErrorBoundary>,
|
|
428
|
+
document.getElementById('root')
|
|
429
|
+
);
|
|
430
|
+
// ✅ All errors captured including React component errors
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
### Node.js - Complete Setup
|
|
434
|
+
|
|
435
|
+
```javascript
|
|
436
|
+
// app.js
|
|
437
|
+
const { register, captureException } = require('@watchforge/browser');
|
|
438
|
+
|
|
439
|
+
// Initialize SDK
|
|
440
|
+
// API URL is automatically derived from DSN host
|
|
441
|
+
register({
|
|
442
|
+
dsn: process.env.WATCHFORGE_DSN,
|
|
443
|
+
app_env: process.env.NODE_ENV || "production",
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
// Global uncaught exception handler
|
|
447
|
+
process.on('uncaughtException', (error) => {
|
|
448
|
+
captureException(error);
|
|
449
|
+
process.exit(1);
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
// Global unhandled rejection handler
|
|
453
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
454
|
+
captureException(reason);
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
// Your application code
|
|
458
|
+
async function main() {
|
|
459
|
+
try {
|
|
460
|
+
// your code
|
|
461
|
+
} catch (error) {
|
|
462
|
+
captureException(error);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
main();
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
## Environment Variables
|
|
470
|
+
|
|
471
|
+
### Development (.env)
|
|
472
|
+
|
|
473
|
+
```bash
|
|
474
|
+
WATCHFORGE_DSN=https://PUBLIC_KEY@watchforge.io/PROJECT_ID
|
|
475
|
+
WATCHFORGE_API_URL=http://127.0.0.1:8001/api/ingestion/events/
|
|
476
|
+
NODE_ENV=development
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
### Production
|
|
480
|
+
|
|
481
|
+
```bash
|
|
482
|
+
WATCHFORGE_DSN=https://PUBLIC_KEY@watchforge.io/PROJECT_ID
|
|
483
|
+
NODE_ENV=production
|
|
484
|
+
# Don't set WATCHFORGE_API_URL - uses DSN-derived URL
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
## Automatic Capture
|
|
488
|
+
|
|
489
|
+
The SDK automatically captures errors when you call `register()`:
|
|
490
|
+
|
|
491
|
+
### Browser (React) - Auto-captured (NO setup needed)
|
|
492
|
+
- ✅ `window.onerror` - Uncaught JavaScript errors
|
|
493
|
+
- ✅ `window.onunhandledrejection` - Unhandled promise rejections
|
|
494
|
+
- ✅ Errors in event handlers
|
|
495
|
+
- ✅ Errors in async code
|
|
496
|
+
- ⚠️ React component errors - Requires `<ErrorBoundary>` wrapper
|
|
497
|
+
|
|
498
|
+
### Node.js - Auto-captured
|
|
499
|
+
- ✅ `process.on('uncaughtException')` - Uncaught exceptions
|
|
500
|
+
- ✅ `process.on('unhandledRejection')` - Unhandled promise rejections
|
|
501
|
+
|
|
502
|
+
### Express.js - Requires middleware
|
|
503
|
+
- ⚠️ Express errors - Requires `app.use(expressMiddleware())`
|
|
504
|
+
- ✅ Request context (URL, method, headers, user) - Auto-included with middleware
|
|
505
|
+
|
|
506
|
+
## Manual Capture
|
|
507
|
+
|
|
508
|
+
You can also manually capture:
|
|
509
|
+
|
|
510
|
+
```javascript
|
|
511
|
+
import { captureException, captureMessage } from '@watchforge/browser';
|
|
512
|
+
|
|
513
|
+
// Capture exception
|
|
514
|
+
try {
|
|
515
|
+
// code
|
|
516
|
+
} catch (error) {
|
|
517
|
+
captureException(error);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
// Capture message
|
|
521
|
+
captureMessage("User action", "info");
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
## Best Practices
|
|
525
|
+
|
|
526
|
+
1. **Initialize early**: Call `register()` as early as possible in your application
|
|
527
|
+
2. **Use environment variables**: Don't hardcode DSNs
|
|
528
|
+
3. **Set user context**: Include user information in error context
|
|
529
|
+
4. **Include request context**: For Express.js, use `expressMiddleware()`
|
|
530
|
+
5. **Use ErrorBoundary in React**: Wrap your app with `<ErrorBoundary>` to catch React component errors (optional but recommended)
|
|
531
|
+
|
|
532
|
+
## Troubleshooting
|
|
533
|
+
|
|
534
|
+
### Events not appearing?
|
|
535
|
+
|
|
536
|
+
1. **Check DSN is correct**
|
|
537
|
+
```javascript
|
|
538
|
+
// Make sure DSN format is: https://PUBLIC_KEY@HOST/PROJECT_ID
|
|
539
|
+
register({
|
|
540
|
+
dsn: "https://...@watchforge.io/...",
|
|
541
|
+
});
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
2. **For local development, use a DSN with localhost or set environment variable**
|
|
545
|
+
```javascript
|
|
546
|
+
// Option 1: Use DSN with localhost
|
|
547
|
+
register({
|
|
548
|
+
dsn: "https://PUBLIC_KEY@127.0.0.1:8001/PROJECT_ID", // ✅ API URL derived from DSN
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
// Option 2: Set environment variable
|
|
552
|
+
// WATCHFORGE_API_URL=http://127.0.0.1:8001/api/ingestion/events/
|
|
553
|
+
register({
|
|
554
|
+
dsn: "https://PUBLIC_KEY@watchforge.io/PROJECT_ID", // ✅ API URL from env var
|
|
555
|
+
});
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
3. **Check backend is running**
|
|
559
|
+
```bash
|
|
560
|
+
# Make sure backend is running on port 8001
|
|
561
|
+
cd watchforge-backend
|
|
562
|
+
python manage.py runserver 8001
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
4. **Enable debug mode**
|
|
566
|
+
```javascript
|
|
567
|
+
register({
|
|
568
|
+
dsn: "...",
|
|
569
|
+
debug: true, // ✅ See debug logs in console
|
|
570
|
+
});
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
5. **Check network connectivity**
|
|
574
|
+
- Open browser DevTools → Network tab
|
|
575
|
+
- Look for POST requests to `/api/ingestion/events/`
|
|
576
|
+
- Check for CORS errors
|
|
577
|
+
|
|
578
|
+
6. **Check browser/Node.js console for errors**
|
|
579
|
+
- Look for SDK initialization messages
|
|
580
|
+
- Check for any error messages
|
|
581
|
+
|
|
582
|
+
### IP address missing?
|
|
583
|
+
|
|
584
|
+
Make sure to include IP address in user context:
|
|
585
|
+
```javascript
|
|
586
|
+
// Express.js - IP is automatically extracted by expressMiddleware()
|
|
587
|
+
app.use(expressMiddleware()); // ✅ Automatically includes IP
|
|
588
|
+
|
|
589
|
+
// Manual capture
|
|
590
|
+
captureException(error, {
|
|
591
|
+
user: {
|
|
592
|
+
id: user.id,
|
|
593
|
+
email: user.email,
|
|
594
|
+
ip_address: req.ip, // ✅ Include IP
|
|
595
|
+
},
|
|
596
|
+
});
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
### Common Issues
|
|
600
|
+
|
|
601
|
+
**Issue: "DSN not set"**
|
|
602
|
+
- Make sure you call `register()` before using `captureException()`
|
|
603
|
+
|
|
604
|
+
**Issue: Events not reaching backend**
|
|
605
|
+
- Check DSN host is correct (API URL is derived from DSN)
|
|
606
|
+
- For local dev, use DSN with `127.0.0.1:8001` or set `WATCHFORGE_API_URL` env var
|
|
607
|
+
- Verify backend is running and accessible
|
|
608
|
+
- Check CORS settings if testing from browser
|
|
609
|
+
|
|
610
|
+
**Issue: No debug output**
|
|
611
|
+
- Set `debug: true` in `register()` options
|
|
612
|
+
- Check console for SDK messages
|
|
613
|
+
|
|
614
|
+
## Testing Your Setup
|
|
615
|
+
|
|
616
|
+
### Step 1: Start Your Backend
|
|
617
|
+
|
|
618
|
+
Make sure your WatchForge backend is running:
|
|
619
|
+
|
|
620
|
+
```bash
|
|
621
|
+
cd watchforge-backend
|
|
622
|
+
python manage.py runserver 8001
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
### Step 2: Test Node.js SDK
|
|
626
|
+
|
|
627
|
+
```bash
|
|
628
|
+
# In watchforge-javascript-sdk directory
|
|
629
|
+
node test-node.js
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
**Expected Output:**
|
|
633
|
+
```
|
|
634
|
+
✅ WatchForge SDK initialized for Node.js
|
|
635
|
+
📝 Test 1: Capturing exception...
|
|
636
|
+
✅ Exception captured
|
|
637
|
+
📝 Test 2: Capturing exception with context...
|
|
638
|
+
✅ Exception with context captured
|
|
639
|
+
...
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
**Check Backend Logs:**
|
|
643
|
+
You should see events appearing in your backend logs at `/api/ingestion/events/`
|
|
644
|
+
|
|
645
|
+
### Step 3: Test Express.js SDK
|
|
646
|
+
|
|
647
|
+
```bash
|
|
648
|
+
# Install Express if needed
|
|
649
|
+
npm install express
|
|
650
|
+
|
|
651
|
+
# Run test server
|
|
652
|
+
node test-express.js
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
**Then visit:**
|
|
656
|
+
- `http://localhost:3000/ok` - Should return JSON
|
|
657
|
+
- `http://localhost:3000/error` - Will trigger error (check backend logs)
|
|
658
|
+
|
|
659
|
+
### Step 4: Verify Events in Backend
|
|
660
|
+
|
|
661
|
+
Check your backend terminal/logs for:
|
|
662
|
+
```
|
|
663
|
+
POST /api/ingestion/events/ - 201 Created
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
Or check the Django admin or your database for new events.
|
|
667
|
+
|
|
668
|
+
### Test DSN (for local testing)
|
|
669
|
+
|
|
670
|
+
Use this DSN for local development:
|
|
671
|
+
```
|
|
672
|
+
https://91960c09176bb2e7d0909156db1aa5c4ec44eba5e7b862a84f0de952077756c9@watchforge.io/5edc2191-c7ff-4341-ae45-c8693d16f689
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
And set:
|
|
676
|
+
```javascript
|
|
677
|
+
// For local development, use DSN with 127.0.0.1:8001
|
|
678
|
+
register({
|
|
679
|
+
dsn: "https://91960c09176bb2e7d0909156db1aa5c4ec44eba5e7b862a84f0de952077756c9@127.0.0.1:8001/5edc2191-c7ff-4341-ae45-c8693d16f689",
|
|
680
|
+
app_env: "development",
|
|
681
|
+
debug: true, // Enable to see debug logs
|
|
682
|
+
});
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
## Complete Examples
|
|
686
|
+
|
|
687
|
+
### Example 1: Minimal Node.js Setup
|
|
688
|
+
|
|
689
|
+
```javascript
|
|
690
|
+
// app.js
|
|
691
|
+
const { register, captureException } = require('@watchforge/browser');
|
|
692
|
+
|
|
693
|
+
// Initialize
|
|
694
|
+
// API URL is automatically derived from DSN host
|
|
695
|
+
register({
|
|
696
|
+
dsn: "https://PUBLIC_KEY@watchforge.io/PROJECT_ID",
|
|
697
|
+
app_env: "production",
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
// Use
|
|
701
|
+
try {
|
|
702
|
+
// your code
|
|
703
|
+
} catch (error) {
|
|
704
|
+
captureException(error);
|
|
705
|
+
}
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
### Example 2: Express.js with Error Handling
|
|
709
|
+
|
|
710
|
+
```javascript
|
|
711
|
+
// server.js
|
|
712
|
+
const express = require('express');
|
|
713
|
+
const { register, expressMiddleware } = require('@watchforge/browser');
|
|
714
|
+
|
|
715
|
+
const app = express();
|
|
716
|
+
|
|
717
|
+
register({
|
|
718
|
+
dsn: process.env.WATCHFORGE_DSN,
|
|
719
|
+
app_env: process.env.NODE_ENV,
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
// Add error handler (must be last middleware)
|
|
723
|
+
app.use(expressMiddleware());
|
|
724
|
+
|
|
725
|
+
app.listen(3000);
|
|
726
|
+
```
|
|
727
|
+
|
|
728
|
+
### Example 3: React with Error Boundary
|
|
729
|
+
|
|
730
|
+
```javascript
|
|
731
|
+
// src/index.js
|
|
732
|
+
import { register, ErrorBoundary } from '@watchforge/browser';
|
|
733
|
+
import App from './App';
|
|
734
|
+
|
|
735
|
+
register({
|
|
736
|
+
dsn: process.env.REACT_APP_WATCHFORGE_DSN,
|
|
737
|
+
app_env: process.env.NODE_ENV,
|
|
738
|
+
});
|
|
739
|
+
|
|
740
|
+
ReactDOM.render(
|
|
741
|
+
<ErrorBoundary>
|
|
742
|
+
<App />
|
|
743
|
+
</ErrorBoundary>,
|
|
744
|
+
document.getElementById('root')
|
|
745
|
+
);
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
## Test Scripts
|
|
749
|
+
|
|
750
|
+
Test scripts are included in the SDK directory:
|
|
751
|
+
- `test-node.js` - Test Node.js SDK
|
|
752
|
+
- `test-express.js` - Test Express.js SDK
|
|
753
|
+
- `test-react.html` - Test React SDK (HTML example)
|
|
754
|
+
|
|
755
|
+
Run them to verify your setup is working correctly!
|