@echoteam/signoz-react 1.2.7 → 1.2.10
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/TROUBLESHOOTING.md +76 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.esm.js +166 -38
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +166 -38
- package/dist/index.js.map +1 -1
- package/dist/types/tracing.d.ts +1 -0
- package/package.json +1 -1
package/TROUBLESHOOTING.md
CHANGED
|
@@ -1,5 +1,81 @@
|
|
|
1
1
|
# Troubleshooting Guide
|
|
2
2
|
|
|
3
|
+
## Error: Timeout from BatchSpanProcessor
|
|
4
|
+
|
|
5
|
+
### Masalah
|
|
6
|
+
Jika Anda mendapatkan error seperti ini di console:
|
|
7
|
+
```
|
|
8
|
+
Unhandled Promise rejection: Timeout ; Zone: <root> ; Task: Promise.then ; Value: Error: Timeout
|
|
9
|
+
at BatchSpanProcessorBase.js:132:1
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
### Penyebab
|
|
13
|
+
Error ini terjadi ketika BatchSpanProcessor mencoba mengirim spans ke backend SignOz tetapi mengalami timeout. Ini biasanya terjadi karena:
|
|
14
|
+
1. Backend SignOz tidak dapat dijangkau
|
|
15
|
+
2. Network lambat atau tidak stabil
|
|
16
|
+
3. CORS tidak dikonfigurasi dengan benar di backend
|
|
17
|
+
4. Timeout terlalu pendek untuk koneksi Anda
|
|
18
|
+
|
|
19
|
+
### Solusi
|
|
20
|
+
|
|
21
|
+
#### 1. Verifikasi Backend SignOz Dapat Dijangkau
|
|
22
|
+
Pastikan URL SignOz Anda benar dan dapat diakses dari browser:
|
|
23
|
+
```javascript
|
|
24
|
+
// Test di browser console
|
|
25
|
+
fetch('http://your-signoz-url:4318/v1/traces', {
|
|
26
|
+
method: 'POST',
|
|
27
|
+
headers: { 'Content-Type': 'application/json' }
|
|
28
|
+
})
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
#### 2. Periksa CORS Configuration
|
|
32
|
+
Pastikan backend SignOz Anda mengizinkan request dari domain frontend Anda. Lihat [BACKEND_CORS_SETUP.md](./BACKEND_CORS_SETUP.md) untuk panduan lengkap.
|
|
33
|
+
|
|
34
|
+
#### 3. Tingkatkan Timeout (Recommended)
|
|
35
|
+
Sejak versi 1.2.10, timeout default sudah ditingkatkan menjadi 60 detik. Jika masih timeout, Anda bisa meningkatkannya lebih lanjut:
|
|
36
|
+
|
|
37
|
+
```javascript
|
|
38
|
+
import { initializeSignOzTracing } from '@echoteam/signoz-react';
|
|
39
|
+
|
|
40
|
+
initializeSignOzTracing({
|
|
41
|
+
serviceName: 'my-app',
|
|
42
|
+
serviceVersion: '1.0.0',
|
|
43
|
+
environment: 'production',
|
|
44
|
+
serviceNamespace: 'frontend',
|
|
45
|
+
url: 'http://your-signoz-url:4318/v1/traces',
|
|
46
|
+
batchSpanProcessorConfig: {
|
|
47
|
+
maxQueueSize: 100,
|
|
48
|
+
scheduledDelayMillis: 5000,
|
|
49
|
+
exportTimeoutMillis: 120000, // 120 seconds
|
|
50
|
+
maxExportBatchSize: 50
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
#### 4. Suppress Timeout Errors (Jika Tidak Mengganggu)
|
|
56
|
+
Sejak versi 1.2.10, timeout errors dari BatchSpanProcessor secara otomatis di-suppress untuk menghindari noise di console. Error ini biasanya aman untuk diabaikan karena spans akan di-retry atau di-queue ulang.
|
|
57
|
+
|
|
58
|
+
Jika Anda ingin melihat warning untuk timeout ini, aktifkan console logging:
|
|
59
|
+
```javascript
|
|
60
|
+
initializeSignOzTracing({
|
|
61
|
+
// ... config lainnya
|
|
62
|
+
enableConsoleLog: true
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
#### 5. Gunakan Network yang Lebih Stabil
|
|
67
|
+
Jika Anda mengalami timeout secara konsisten, pertimbangkan:
|
|
68
|
+
- Menggunakan koneksi internet yang lebih stabil
|
|
69
|
+
- Mengurangi ukuran batch dengan `maxExportBatchSize`
|
|
70
|
+
- Meningkatkan `scheduledDelayMillis` untuk mengirim spans lebih jarang
|
|
71
|
+
|
|
72
|
+
### Catatan Penting
|
|
73
|
+
- Timeout errors biasanya tidak mempengaruhi fungsionalitas aplikasi Anda
|
|
74
|
+
- Spans yang gagal dikirim akan di-queue ulang dan dicoba lagi
|
|
75
|
+
- Jika backend SignOz tidak dapat dijangkau sama sekali, spans akan di-drop setelah queue penuh
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
3
79
|
## Error: Can't resolve 'perf_hooks'
|
|
4
80
|
|
|
5
81
|
### Masalah
|
package/dist/index.d.ts
CHANGED
package/dist/index.esm.js
CHANGED
|
@@ -15349,7 +15349,8 @@ function addFetchLogging(config) {
|
|
|
15349
15349
|
if (contentLength) {
|
|
15350
15350
|
span.setAttribute('http.response_content_length', parseInt(contentLength));
|
|
15351
15351
|
}
|
|
15352
|
-
|
|
15352
|
+
// Log response body for both success and error responses
|
|
15353
|
+
if (config.logResponseBody) {
|
|
15353
15354
|
const clonedResponse = response.clone();
|
|
15354
15355
|
try {
|
|
15355
15356
|
const responseData = await clonedResponse.text();
|
|
@@ -15365,12 +15366,27 @@ function addFetchLogging(config) {
|
|
|
15365
15366
|
if (jsonData.message) {
|
|
15366
15367
|
span.setAttribute('response.message', jsonData.message);
|
|
15367
15368
|
}
|
|
15369
|
+
// Also log error details if present
|
|
15370
|
+
if (jsonData.errors) {
|
|
15371
|
+
span.setAttribute('response.errors', JSON.stringify(jsonData.errors));
|
|
15372
|
+
}
|
|
15373
|
+
if (jsonData.status !== undefined) {
|
|
15374
|
+
span.setAttribute('response.status', jsonData.status);
|
|
15375
|
+
}
|
|
15376
|
+
if (jsonData.status_code !== undefined) {
|
|
15377
|
+
span.setAttribute('response.status_code', jsonData.status_code);
|
|
15378
|
+
}
|
|
15368
15379
|
}
|
|
15369
15380
|
catch (e) {
|
|
15370
15381
|
// Not JSON or no message field, ignore
|
|
15371
15382
|
}
|
|
15372
15383
|
if (config.enableConsoleLog) {
|
|
15373
|
-
|
|
15384
|
+
if (response.ok) {
|
|
15385
|
+
console.log(`[SignOz] ${method} Response from ${url} (${response.status}) on page ${pagePath} [${Math.round(duration)}ms]:`, truncatedData);
|
|
15386
|
+
}
|
|
15387
|
+
else {
|
|
15388
|
+
console.error(`[SignOz] ${method} Error Response from ${url} (${response.status}) on page ${pagePath} [${Math.round(duration)}ms]:`, truncatedData);
|
|
15389
|
+
}
|
|
15374
15390
|
}
|
|
15375
15391
|
}
|
|
15376
15392
|
catch (e) {
|
|
@@ -15380,7 +15396,7 @@ function addFetchLogging(config) {
|
|
|
15380
15396
|
}
|
|
15381
15397
|
}
|
|
15382
15398
|
else if (!response.ok && config.enableConsoleLog) {
|
|
15383
|
-
console.
|
|
15399
|
+
console.error(`[SignOz] ${method} Request to ${url} from page ${pagePath} - Status: ${response.status} [${Math.round(duration)}ms]`);
|
|
15384
15400
|
}
|
|
15385
15401
|
span.setStatus({ code: SpanStatusCode.OK });
|
|
15386
15402
|
return response;
|
|
@@ -15451,31 +15467,66 @@ function addXHRLogging(config) {
|
|
|
15451
15467
|
if (contentLength) {
|
|
15452
15468
|
span.setAttribute('http.response_content_length', parseInt(contentLength));
|
|
15453
15469
|
}
|
|
15454
|
-
// Log response body
|
|
15455
|
-
if (config.logResponseBody
|
|
15456
|
-
const responseData = xhr.responseText;
|
|
15457
|
-
const truncatedData = truncateBody(responseData, config.maxBodyLogSize);
|
|
15458
|
-
span.setAttribute('response.data', truncatedData);
|
|
15459
|
-
// If content-length header is not available, calculate from response data
|
|
15460
|
-
if (!contentLength) {
|
|
15461
|
-
span.setAttribute('http.response_content_length', responseData.length);
|
|
15462
|
-
}
|
|
15463
|
-
// Try to parse JSON and extract message if exists
|
|
15470
|
+
// Log response body for both success and error responses
|
|
15471
|
+
if (config.logResponseBody) {
|
|
15464
15472
|
try {
|
|
15465
|
-
|
|
15466
|
-
if (
|
|
15467
|
-
|
|
15473
|
+
// Only read responseText if responseType allows it
|
|
15474
|
+
if (xhr.responseType === '' || xhr.responseType === 'text') {
|
|
15475
|
+
const responseData = xhr.responseText;
|
|
15476
|
+
const truncatedData = truncateBody(responseData, config.maxBodyLogSize);
|
|
15477
|
+
span.setAttribute('response.data', truncatedData);
|
|
15478
|
+
// If content-length header is not available, calculate from response data
|
|
15479
|
+
if (!contentLength) {
|
|
15480
|
+
span.setAttribute('http.response_content_length', responseData.length);
|
|
15481
|
+
}
|
|
15482
|
+
// Try to parse JSON and extract message if exists
|
|
15483
|
+
try {
|
|
15484
|
+
const jsonData = JSON.parse(responseData);
|
|
15485
|
+
if (jsonData.message) {
|
|
15486
|
+
span.setAttribute('response.message', jsonData.message);
|
|
15487
|
+
}
|
|
15488
|
+
// Also log error details if present
|
|
15489
|
+
if (jsonData.errors) {
|
|
15490
|
+
span.setAttribute('response.errors', JSON.stringify(jsonData.errors));
|
|
15491
|
+
}
|
|
15492
|
+
if (jsonData.status !== undefined) {
|
|
15493
|
+
span.setAttribute('response.status', jsonData.status);
|
|
15494
|
+
}
|
|
15495
|
+
if (jsonData.status_code !== undefined) {
|
|
15496
|
+
span.setAttribute('response.status_code', jsonData.status_code);
|
|
15497
|
+
}
|
|
15498
|
+
}
|
|
15499
|
+
catch (e) {
|
|
15500
|
+
// Not JSON or no message field, ignore
|
|
15501
|
+
}
|
|
15502
|
+
if (config.enableConsoleLog) {
|
|
15503
|
+
if (xhr.status >= 200 && xhr.status < 300) {
|
|
15504
|
+
console.log(`[SignOz] ${method} Response from ${url} (${xhr.status}) on page ${pagePath} [${Math.round(duration)}ms]:`, truncatedData);
|
|
15505
|
+
}
|
|
15506
|
+
else {
|
|
15507
|
+
console.error(`[SignOz] ${method} Error Response from ${url} (${xhr.status}) on page ${pagePath} [${Math.round(duration)}ms]:`, truncatedData);
|
|
15508
|
+
}
|
|
15509
|
+
}
|
|
15510
|
+
}
|
|
15511
|
+
else {
|
|
15512
|
+
// For other response types (blob, arraybuffer, etc), just log the type
|
|
15513
|
+
span.setAttribute('response.data', `[${xhr.responseType} data]`);
|
|
15514
|
+
span.setAttribute('response.type', xhr.responseType);
|
|
15515
|
+
if (config.enableConsoleLog) {
|
|
15516
|
+
console.log(`[SignOz] ${method} Response from ${url} (${xhr.status}) on page ${pagePath} [${Math.round(duration)}ms]: [${xhr.responseType} data]`);
|
|
15517
|
+
}
|
|
15468
15518
|
}
|
|
15469
15519
|
}
|
|
15470
15520
|
catch (e) {
|
|
15471
|
-
//
|
|
15472
|
-
|
|
15473
|
-
|
|
15474
|
-
|
|
15521
|
+
// If there's an error reading response, log it
|
|
15522
|
+
span.setAttribute('response.data', '[Error reading response]');
|
|
15523
|
+
if (config.enableConsoleLog) {
|
|
15524
|
+
console.warn(`[SignOz] Failed to read response from ${url}:`, e);
|
|
15525
|
+
}
|
|
15475
15526
|
}
|
|
15476
15527
|
}
|
|
15477
15528
|
else if (xhr.status >= 300 && config.enableConsoleLog) {
|
|
15478
|
-
console.
|
|
15529
|
+
console.error(`[SignOz] ${method} Request to ${url} from page ${pagePath} - Status: ${xhr.status} [${Math.round(duration)}ms]`);
|
|
15479
15530
|
}
|
|
15480
15531
|
span.setStatus({ code: SpanStatusCode.OK });
|
|
15481
15532
|
span.end();
|
|
@@ -15508,9 +15559,15 @@ function addErrorTracking(enableConsoleLog = false) {
|
|
|
15508
15559
|
span.setAttribute('error.filename', event.filename || 'unknown');
|
|
15509
15560
|
span.setAttribute('error.lineno', event.lineno || 0);
|
|
15510
15561
|
span.setAttribute('error.colno', event.colno || 0);
|
|
15562
|
+
// Add page context
|
|
15563
|
+
span.setAttribute('page.url', window.location.href);
|
|
15564
|
+
span.setAttribute('page.pathname', window.location.pathname);
|
|
15565
|
+
span.setAttribute('page.search', window.location.search);
|
|
15566
|
+
span.setAttribute('page.hash', window.location.hash);
|
|
15511
15567
|
if (event.error) {
|
|
15512
15568
|
span.recordException(event.error);
|
|
15513
15569
|
span.setAttribute('error.stack', event.error.stack || '');
|
|
15570
|
+
span.setAttribute('error.name', event.error.name || 'Error');
|
|
15514
15571
|
}
|
|
15515
15572
|
span.setStatus({ code: SpanStatusCode.ERROR, message: event.message });
|
|
15516
15573
|
if (enableConsoleLog) {
|
|
@@ -15519,28 +15576,102 @@ function addErrorTracking(enableConsoleLog = false) {
|
|
|
15519
15576
|
filename: event.filename,
|
|
15520
15577
|
lineno: event.lineno,
|
|
15521
15578
|
colno: event.colno,
|
|
15522
|
-
stack: (_a = event.error) === null || _a === void 0 ? void 0 : _a.stack
|
|
15579
|
+
stack: (_a = event.error) === null || _a === void 0 ? void 0 : _a.stack,
|
|
15580
|
+
page: window.location.pathname
|
|
15523
15581
|
});
|
|
15524
15582
|
}
|
|
15525
15583
|
span.end();
|
|
15526
|
-
});
|
|
15584
|
+
}, true); // Use capture phase to catch errors early
|
|
15527
15585
|
// Track unhandled promise rejections
|
|
15528
15586
|
window.addEventListener('unhandledrejection', (event) => {
|
|
15587
|
+
// Suppress BatchSpanProcessor timeout errors to avoid noise
|
|
15588
|
+
const reason = String(event.reason);
|
|
15589
|
+
if (reason.includes('Timeout') && reason.includes('BatchSpanProcessor')) {
|
|
15590
|
+
if (enableConsoleLog) {
|
|
15591
|
+
console.warn('[SignOz] Span export timeout (this is usually safe to ignore):', event.reason);
|
|
15592
|
+
}
|
|
15593
|
+
event.preventDefault(); // Prevent the error from being logged
|
|
15594
|
+
return;
|
|
15595
|
+
}
|
|
15529
15596
|
const tracer = trace.getTracer('error-tracker');
|
|
15530
15597
|
const span = tracer.startSpan('Unhandled Promise Rejection');
|
|
15531
15598
|
span.setAttribute('error.type', 'unhandled_rejection');
|
|
15532
15599
|
span.setAttribute('error.reason', String(event.reason));
|
|
15600
|
+
// Add page context
|
|
15601
|
+
span.setAttribute('page.url', window.location.href);
|
|
15602
|
+
span.setAttribute('page.pathname', window.location.pathname);
|
|
15603
|
+
span.setAttribute('page.search', window.location.search);
|
|
15604
|
+
span.setAttribute('page.hash', window.location.hash);
|
|
15533
15605
|
if (event.reason instanceof Error) {
|
|
15534
15606
|
span.recordException(event.reason);
|
|
15535
15607
|
span.setAttribute('error.message', event.reason.message);
|
|
15536
15608
|
span.setAttribute('error.stack', event.reason.stack || '');
|
|
15609
|
+
span.setAttribute('error.name', event.reason.name || 'Error');
|
|
15537
15610
|
}
|
|
15538
15611
|
span.setStatus({ code: SpanStatusCode.ERROR, message: String(event.reason) });
|
|
15539
15612
|
if (enableConsoleLog) {
|
|
15540
|
-
console.error('[SignOz] Unhandled Promise Rejection:', event.reason);
|
|
15613
|
+
console.error('[SignOz] Unhandled Promise Rejection:', event.reason, 'on page', window.location.pathname);
|
|
15541
15614
|
}
|
|
15542
15615
|
span.end();
|
|
15543
15616
|
});
|
|
15617
|
+
// Track Zone.js errors (for Angular/React with zone.js)
|
|
15618
|
+
if (typeof Zone !== 'undefined' && Zone.current) {
|
|
15619
|
+
const currentZone = Zone.current;
|
|
15620
|
+
const originalHandleError = currentZone.handleError;
|
|
15621
|
+
if (originalHandleError) {
|
|
15622
|
+
currentZone.handleError = function (error) {
|
|
15623
|
+
const tracer = trace.getTracer('error-tracker');
|
|
15624
|
+
const span = tracer.startSpan('Zone.js Error');
|
|
15625
|
+
span.setAttribute('error.type', 'zone_error');
|
|
15626
|
+
span.setAttribute('error.message', error.message || String(error));
|
|
15627
|
+
span.setAttribute('error.name', error.name || 'Error');
|
|
15628
|
+
// Add page context
|
|
15629
|
+
span.setAttribute('page.url', window.location.href);
|
|
15630
|
+
span.setAttribute('page.pathname', window.location.pathname);
|
|
15631
|
+
span.setAttribute('page.search', window.location.search);
|
|
15632
|
+
span.setAttribute('page.hash', window.location.hash);
|
|
15633
|
+
if (error.stack) {
|
|
15634
|
+
span.setAttribute('error.stack', error.stack);
|
|
15635
|
+
}
|
|
15636
|
+
span.recordException(error);
|
|
15637
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: error.message || String(error) });
|
|
15638
|
+
if (enableConsoleLog) {
|
|
15639
|
+
console.error('[SignOz] Zone.js Error:', error, 'on page', window.location.pathname);
|
|
15640
|
+
}
|
|
15641
|
+
span.end();
|
|
15642
|
+
// Call original handler
|
|
15643
|
+
return originalHandleError.call(currentZone, error);
|
|
15644
|
+
};
|
|
15645
|
+
}
|
|
15646
|
+
}
|
|
15647
|
+
// Override console.error to catch React errors
|
|
15648
|
+
const originalConsoleError = console.error;
|
|
15649
|
+
console.error = function (...args) {
|
|
15650
|
+
// Check if this is a React error
|
|
15651
|
+
const errorMessage = args.map(arg => String(arg)).join(' ');
|
|
15652
|
+
if (errorMessage.includes('React') || errorMessage.includes('TypeError') || errorMessage.includes('Uncaught')) {
|
|
15653
|
+
const tracer = trace.getTracer('error-tracker');
|
|
15654
|
+
const span = tracer.startSpan('Console Error');
|
|
15655
|
+
span.setAttribute('error.type', 'console_error');
|
|
15656
|
+
span.setAttribute('error.message', errorMessage);
|
|
15657
|
+
// Add page context
|
|
15658
|
+
span.setAttribute('page.url', window.location.href);
|
|
15659
|
+
span.setAttribute('page.pathname', window.location.pathname);
|
|
15660
|
+
span.setAttribute('page.search', window.location.search);
|
|
15661
|
+
span.setAttribute('page.hash', window.location.hash);
|
|
15662
|
+
// Try to extract stack trace
|
|
15663
|
+
const errorObj = args.find(arg => arg instanceof Error);
|
|
15664
|
+
if (errorObj) {
|
|
15665
|
+
span.recordException(errorObj);
|
|
15666
|
+
span.setAttribute('error.stack', errorObj.stack || '');
|
|
15667
|
+
span.setAttribute('error.name', errorObj.name || 'Error');
|
|
15668
|
+
}
|
|
15669
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: errorMessage });
|
|
15670
|
+
span.end();
|
|
15671
|
+
}
|
|
15672
|
+
// Call original console.error
|
|
15673
|
+
return originalConsoleError.apply(console, args);
|
|
15674
|
+
};
|
|
15544
15675
|
}
|
|
15545
15676
|
// Fungsi untuk menambahkan navigation tracking
|
|
15546
15677
|
function addNavigationTracking(enableConsoleLog = false) {
|
|
@@ -15862,7 +15993,8 @@ function initializeSignOzTracing(config) {
|
|
|
15862
15993
|
batchSpanProcessorConfig: (config === null || config === void 0 ? void 0 : config.batchSpanProcessorConfig) || {
|
|
15863
15994
|
maxQueueSize: 100,
|
|
15864
15995
|
scheduledDelayMillis: 5000,
|
|
15865
|
-
exportTimeoutMillis:
|
|
15996
|
+
exportTimeoutMillis: 60000, // Increased to 60 seconds
|
|
15997
|
+
maxExportBatchSize: 50 // Smaller batches to avoid timeouts
|
|
15866
15998
|
},
|
|
15867
15999
|
allowedOrigins: (config === null || config === void 0 ? void 0 : config.allowedOrigins) || parseAllowedOrigins(getConfigValue('REACT_APP_SIGNOZ_ALLOWED_ORIGINS')),
|
|
15868
16000
|
enableRequestLogging: (config === null || config === void 0 ? void 0 : config.enableRequestLogging) !== undefined ? config.enableRequestLogging : (getConfigValue('REACT_APP_SIGNOZ_ENABLE_REQUEST_LOGGING') === 'true' || true),
|
|
@@ -15893,7 +16025,8 @@ function initializeSignOzTracing(config) {
|
|
|
15893
16025
|
// Set up the OTLP trace exporter
|
|
15894
16026
|
const exporter = new OTLPTraceExporter({
|
|
15895
16027
|
url: effectiveConfig.url,
|
|
15896
|
-
headers: effectiveConfig.headers
|
|
16028
|
+
headers: effectiveConfig.headers,
|
|
16029
|
+
timeoutMillis: 60000 // Set exporter timeout to 60 seconds
|
|
15897
16030
|
});
|
|
15898
16031
|
// Set up the span processor with configuration
|
|
15899
16032
|
const processor = new BatchSpanProcessor(exporter, {
|
|
@@ -16103,17 +16236,6 @@ function hasArrayChanged() {
|
|
|
16103
16236
|
}
|
|
16104
16237
|
|
|
16105
16238
|
const DefaultErrorFallback = ({ error, resetErrorBoundary }) => {
|
|
16106
|
-
const serviceName = window.REACT_APP_SIGNOZ_SERVICE_NAME || 'react-app';
|
|
16107
|
-
const tracer = trace.getTracer(serviceName);
|
|
16108
|
-
const span = tracer.startSpan(serviceName + ".error");
|
|
16109
|
-
React2__default.useEffect(() => {
|
|
16110
|
-
span.setAttribute('error.message', error.message);
|
|
16111
|
-
span.setAttribute('error.stack', JSON.stringify(error.stack));
|
|
16112
|
-
span.setAttribute('error.name', error.name);
|
|
16113
|
-
span.recordException(error);
|
|
16114
|
-
span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
|
|
16115
|
-
span.end();
|
|
16116
|
-
}, [error, span]);
|
|
16117
16239
|
return (jsxs("div", { role: "alert", className: "error-boundary-fallback", children: [jsx("h1", { children: "Oops!" }), jsx("p", { children: "Terjadi kesalahan yang tidak terduga." }), jsx("p", { children: jsx("i", { children: error.statusText || error.message }) }), jsx("button", { onClick: resetErrorBoundary, children: "Coba lagi" })] }));
|
|
16118
16240
|
};
|
|
16119
16241
|
const ErrorBoundary = ({ children, fallback: FallbackComponent, onError, onReset, showResetButton = true, resetButtonText = "Coba lagi", fallbackClassName = "", }) => {
|
|
@@ -16122,10 +16244,16 @@ const ErrorBoundary = ({ children, fallback: FallbackComponent, onError, onReset
|
|
|
16122
16244
|
const serviceName = window.REACT_APP_SIGNOZ_SERVICE_NAME || 'react-app';
|
|
16123
16245
|
const tracer = trace.getTracer(serviceName);
|
|
16124
16246
|
const span = tracer.startSpan(serviceName + ".error");
|
|
16247
|
+
span.setAttribute('error.type', 'react_error_boundary');
|
|
16125
16248
|
span.setAttribute('error.message', error.message);
|
|
16126
|
-
span.setAttribute('error.stack',
|
|
16249
|
+
span.setAttribute('error.stack', error.stack || '');
|
|
16127
16250
|
span.setAttribute('error.name', error.name);
|
|
16128
16251
|
span.setAttribute('error.componentStack', errorInfo.componentStack || '');
|
|
16252
|
+
// Add page context
|
|
16253
|
+
span.setAttribute('page.url', window.location.href);
|
|
16254
|
+
span.setAttribute('page.pathname', window.location.pathname);
|
|
16255
|
+
span.setAttribute('page.search', window.location.search);
|
|
16256
|
+
span.setAttribute('page.hash', window.location.hash);
|
|
16129
16257
|
span.recordException(error);
|
|
16130
16258
|
span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
|
|
16131
16259
|
span.end();
|