Skip to content

Commit 37cea2f

Browse files
authored
Merge pull request #253 from flashcatcloud/docs/electron-user-first-guide
docs(rum): simplify Electron SDK guides
2 parents ecce0a8 + cc4d3a1 commit 37cea2f

13 files changed

Lines changed: 1448 additions & 2121 deletions

docs.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,7 +1736,9 @@
17361736
"zh/rum/sdk/electron/sdk-integration",
17371737
"zh/rum/sdk/electron/advanced-config",
17381738
"zh/rum/sdk/electron/compatible",
1739-
"zh/rum/sdk/electron/data-collection"
1739+
"zh/rum/sdk/electron/data-collection",
1740+
"zh/rum/sdk/electron/error-symbolication",
1741+
"zh/rum/sdk/electron/faq"
17401742
]
17411743
},
17421744
{
@@ -3064,7 +3066,9 @@
30643066
"en/rum/sdk/electron/sdk-integration",
30653067
"en/rum/sdk/electron/advanced-config",
30663068
"en/rum/sdk/electron/compatible",
3067-
"en/rum/sdk/electron/data-collection"
3069+
"en/rum/sdk/electron/data-collection",
3070+
"en/rum/sdk/electron/error-symbolication",
3071+
"en/rum/sdk/electron/faq"
30683072
]
30693073
},
30703074
{

en/rum/sdk/electron/advanced-config.mdx

Lines changed: 162 additions & 436 deletions
Large diffs are not rendered by default.

en/rum/sdk/electron/compatible.mdx

Lines changed: 58 additions & 79 deletions
Large diffs are not rendered by default.

en/rum/sdk/electron/data-collection.mdx

Lines changed: 97 additions & 261 deletions
Large diffs are not rendered by default.
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
---
2+
title: "Electron error symbolication"
3+
description: "Upload JavaScript source maps and native crash symbols for an Electron application to restore production stack traces"
4+
keywords: ["RUM", "Electron", "source maps", "Breakpad", "native crash", "symbolication"]
5+
---
6+
7+
Electron applications produce JavaScript errors and native crashes. Each stack type uses a different symbolication workflow:
8+
9+
| Error type | Original stack | Upload required |
10+
|------------|----------------|-----------------|
11+
| Main-process and renderer JavaScript errors | Minified file name, line, and column | Build-generated source maps |
12+
| Electron or native module crash | Module name and memory address | Breakpad `.sym` files |
13+
14+
## Symbolicate JavaScript errors
15+
16+
By default, the SDK converts stack frames under the application directory to stable `app:///<relative path>` URLs. The same build produces the same path regardless of where a user installs the application.
17+
18+
For example:
19+
20+
```text
21+
Error: something went wrong
22+
at handleClick @ app:///dist/renderer/index.js:97:15
23+
```
24+
25+
Use only the URL path when uploading. The directory prefix for this example is `/dist/renderer`.
26+
27+
### 1. Align service and version
28+
29+
Flashduty matches a source map using:
30+
31+
- Event `service`
32+
- Event `version`
33+
- Minified file path in the stack frame
34+
35+
Use the same release version in both processes:
36+
37+
```ts main.ts
38+
await init({
39+
// Other options
40+
service: 'my-electron-app',
41+
version: '1.4.2',
42+
});
43+
```
44+
45+
```ts renderer.ts
46+
flashcatRum.init({
47+
// Other options
48+
service: 'my-electron-app',
49+
version: '1.4.2',
50+
});
51+
```
52+
53+
The main-process `version` is not copied to renderer events, so both processes must set it.
54+
55+
### 2. Generate source maps
56+
57+
Enable source maps for main-process and renderer builds:
58+
59+
<CodeGroup>
60+
```ts Vite
61+
export default defineConfig({
62+
build: { sourcemap: true },
63+
});
64+
```
65+
66+
```js Webpack
67+
module.exports = {
68+
mode: 'production',
69+
devtool: 'source-map',
70+
};
71+
```
72+
73+
```ts esbuild
74+
await esbuild.build({
75+
sourcemap: true,
76+
});
77+
```
78+
</CodeGroup>
79+
80+
### 3. Upload main-process and renderer artifacts
81+
82+
Install the [Flashduty CLI](https://github.com/flashcatcloud/flashcat-cli), then upload source maps for each process separately:
83+
84+
```bash
85+
npm install --global @flashcatcloud/flashcat-cli
86+
```
87+
88+
```bash
89+
# Main-process stack: app:///dist/main/index.js
90+
flashcat-cli sourcemaps upload ./out/main \
91+
--service my-electron-app \
92+
--release-version 1.4.2 \
93+
--minified-path-prefix /dist/main \
94+
--api-key <YOUR_API_KEY>
95+
96+
# Renderer stack: app:///dist/renderer/index.js
97+
flashcat-cli sourcemaps upload ./out/renderer \
98+
--service my-electron-app \
99+
--release-version 1.4.2 \
100+
--minified-path-prefix /dist/renderer \
101+
--api-key <YOUR_API_KEY>
102+
```
103+
104+
`--minified-path-prefix` must match the directory shown in the stack frame. Do not include `app:///` in the prefix.
105+
106+
<Warning>
107+
Do not package `.map` files in the distributed application. Exclude them from the release artifact after upload and before creating the installer.
108+
</Warning>
109+
110+
### Custom path mapping
111+
112+
Most projects can use the default `app:///` paths. Set `normalizeStackPath` only when your build directory cannot be represented relative to the application root:
113+
114+
```ts main.ts
115+
await init({
116+
// Other options
117+
normalizeStackPath: (absolutePath) => {
118+
const normalized = absolutePath.replace(/\\/g, '/');
119+
const match = /\/public(\/dist\/.+)$/.exec(normalized);
120+
return match ? match[1] : undefined;
121+
},
122+
});
123+
```
124+
125+
This callback applies to main-process and bridged renderer stacks. Returning `undefined` lets the SDK apply its default rule.
126+
127+
## Symbolicate native crashes
128+
129+
Native crashes come from Electron `crashReporter` minidumps. Without symbols, the stack contains modules and addresses:
130+
131+
```text
132+
0 Electron Framework 0x000000010ab12345
133+
1 libsystem_kernel 0x00007ff81a2b3c4d
134+
```
135+
136+
After matching Breakpad symbols are uploaded, Flashduty can restore function names, file names, and line numbers.
137+
138+
### 1. Prepare symbol files
139+
140+
Download the symbol bundle from [Electron releases](https://github.com/electron/electron/releases) that exactly matches the Electron **version, operating system, and CPU architecture** you ship:
141+
142+
```text
143+
electron-v<version>-<platform>-<arch>-symbols.zip
144+
```
145+
146+
Most frames in a native crash are usually inside Electron modules, so upload the official Electron symbols first.
147+
148+
If the application includes native modules or `.node` plugins, use [dump_syms](https://github.com/mozilla/dump_syms) to generate `.sym` files for them.
149+
150+
### 2. Upload symbols
151+
152+
Place the `.sym` files under one directory, then run:
153+
154+
```bash
155+
flashcat-cli electron-symbols upload ./breakpad_symbols \
156+
--service my-electron-app \
157+
--release-version 1.4.2
158+
```
159+
160+
Use `--dry-run` to preview the files before uploading.
161+
162+
Native symbols match by module ID. `service` and `release-version` label the upload batch for discovery; they do not participate in symbol matching. This differs from JavaScript source maps.
163+
164+
### 3. Publish symbols with each release
165+
166+
Module IDs can change whenever Electron is upgraded or a native module is rebuilt. Upload symbols for every operating system and CPU architecture that you ship.
167+
168+
Missing symbols do not prevent crash reporting. You can receive a crash with address-only frames and upload symbols later; historical crashes are symbolicated when viewed.
169+
170+
## Verify symbolication
171+
172+
### JavaScript errors
173+
174+
1. Trigger an error with a stable stack in a test build.
175+
2. Confirm the event `service` and `version` in error details.
176+
3. Compare the stack frame path with `--minified-path-prefix`.
177+
4. Confirm that error details show the original file, function, and source location.
178+
179+
### Native crashes
180+
181+
1. Trigger a test crash using the same Electron build as the release.
182+
2. Restart the application so the SDK can report the minidump.
183+
3. Confirm that Electron module frames display function names and line numbers.
184+
185+
If upload succeeds but the stack remains unresolved, see [Electron SDK troubleshooting](/en/rum/sdk/electron/faq#why-did-a-source-map-upload-succeed-without-restoring-the-stack).
186+
187+
## Related pages
188+
189+
<CardGroup cols={2}>
190+
<Card title="Advanced configuration" icon="sliders" href="/en/rum/sdk/electron/advanced-config">
191+
Configure versions, path mapping, and other advanced options.
192+
</Card>
193+
194+
<Card title="Data collection" icon="database" href="/en/rum/sdk/electron/data-collection">
195+
Learn how JavaScript errors and native crashes are collected.
196+
</Card>
197+
</CardGroup>

en/rum/sdk/electron/faq.mdx

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
---
2+
title: "Electron SDK troubleshooting"
3+
description: "Troubleshoot missing Electron RUM data, process bridging, Session Replay, and stack symbolication"
4+
keywords: ["RUM", "Electron SDK", "troubleshooting", "Session Replay", "bridge", "source maps"]
5+
---
6+
7+
Use the symptom you see in the application or Flashduty console to find the relevant checks.
8+
9+
<AccordionGroup>
10+
<Accordion title="Why is there no data in the console?">
11+
Check the following in order:
12+
13+
1. Confirm that main-process `init()` returns `true`, and check the main-process console for configuration errors.
14+
2. Confirm that `applicationId`, `clientToken`, and `service` are non-empty strings.
15+
3. Confirm that the application can reach `https://browser.flashcat.cloud/api/v2/rum` or your self-hosted endpoint.
16+
4. Wait for one upload cycle. Regular RUM events upload every 10 seconds by default.
17+
5. Filter with `source:electron OR container.source:electron` in the Explorer.
18+
19+
During integration testing, set `batchSize: 'SMALL'` and `uploadFrequency: 'FREQUENT'` to shorten the wait.
20+
</Accordion>
21+
22+
<Accordion title="Why do I only see main-process data?">
23+
If `source: electron` events appear but renderer views, actions, and resources do not, check that:
24+
25+
1. The renderer installs and initializes `@flashcatcloud/browser-rum`.
26+
2. The main process finishes `init()` before creating a `BrowserWindow`.
27+
3. For an unbundled main process, `instrument` is imported before `electron`.
28+
4. For a bundled main process, the matching Vite, Webpack, or esbuild plugin is configured.
29+
30+
After successful renderer integration, renderer events contain `container.source: electron`.
31+
</Accordion>
32+
33+
<Accordion title="Why is container.source missing from renderer events?">
34+
A missing `container.source` means the Browser SDK did not use the Electron bridge and uploaded as a standalone web page.
35+
36+
Common causes include:
37+
38+
- The main process did not start instrumentation.
39+
- The bundle did not preserve the Electron SDK or its preload.
40+
- SDK initialization failed.
41+
42+
First, verify the build setup under [Integration steps](/en/rum/sdk/electron/sdk-integration#integration-steps), then restart the application.
43+
44+
The current window does not need `allowedWebViewHosts`. Use that option only for third-party pages in a `<webview>` or `BrowserView`.
45+
</Accordion>
46+
47+
<Accordion title="Why is Session Replay missing?">
48+
Check each requirement:
49+
50+
1. `@flashcatcloud/browser-rum` is version 0.0.7 or later.
51+
2. The renderer sets both `sessionReplaySampleRate` and `sessionReplayDirectUpload: true`.
52+
3. `sessionReplaySampleRate` is greater than 0 and the current session is sampled.
53+
4. The page CSP allows `worker-src blob:`.
54+
5. The CSP `connect-src` contains the actual replay upload endpoint.
55+
6. A self-hosted deployment sets `proxy` in the renderer.
56+
57+
Open the renderer DevTools Console and Network panels. A blocked Worker produces a CSP error in Console. An invalid upload endpoint produces failed replay requests in Network.
58+
</Accordion>
59+
60+
<Accordion title="Why is part of a replay missing or visually corrupted?">
61+
The renderer uploads replay segments directly and does not use the main-process disk buffer.
62+
63+
When the device is truly offline, the Browser SDK places segments in an in-memory queue and retries after connectivity returns. If the device appears online but a request fails because of DNS, a proxy, gateway, security software, or an intake outage, the failed segment is not queued. Later segments may not contain the full snapshot needed to reconstruct the page, causing a gap or visual corruption.
64+
65+
Check that:
66+
67+
- Firewalls and endpoint security software allow the upload host.
68+
- DNS and proxy settings can reach the endpoint reliably.
69+
- The page CSP allows the actual replay endpoint.
70+
- Your self-hosted forwarding service remains available.
71+
72+
A segment that was already dropped cannot be recovered from main-process storage.
73+
</Accordion>
74+
75+
<Accordion title="Why does a self-hosted deployment receive regular events but no replay?">
76+
Regular RUM events and Session Replay use separate upload paths:
77+
78+
- Regular events are bridged to the main process and use main-process `site` or `proxy`.
79+
- Replay segments upload directly from the renderer and use the renderer Browser SDK `proxy`.
80+
81+
Configuring only the main process does not change the replay endpoint. Set `proxy` in `flashcatRum.init()` and add it to the page CSP `connect-src` directive.
82+
83+
See [Custom upload endpoints](/en/rum/sdk/electron/advanced-config#custom-upload-endpoints) for a complete example.
84+
</Accordion>
85+
86+
<Accordion title="Why did a source map upload succeed without restoring the stack?">
87+
Flashduty matches source maps using `service`, `version`, and the minified file path. Check that:
88+
89+
1. `--service` matches the process that produced the error.
90+
2. `--release-version` matches that process's `version`.
91+
3. The renderer also sets `version`; the main-process version does not propagate to renderer events.
92+
4. `--minified-path-prefix` matches the directory in the stack frame shown in error details.
93+
5. Main-process and renderer artifacts were uploaded separately.
94+
95+
For `app:///dist/renderer/index.js`, use `/dist/renderer` as the prefix. Do not include `app:///`.
96+
97+
See [Electron error symbolication](/en/rum/sdk/electron/error-symbolication#symbolicate-javascript-errors) for the complete workflow.
98+
</Accordion>
99+
100+
<Accordion title="Why do native crash stacks contain only addresses?">
101+
Native minidumps do not use JavaScript source maps. Upload Breakpad symbols that match the exact application release, operating system, and CPU architecture.
102+
103+
Start with the official symbol bundle for your Electron version. If the application includes native modules or `.node` plugins, generate and upload `.sym` files for those modules as well.
104+
105+
After upload, historical crashes can also be symbolicated when viewed. See [Symbolicate native crashes](/en/rum/sdk/electron/error-symbolication#symbolicate-native-crashes).
106+
</Accordion>
107+
</AccordionGroup>
108+
109+
## If the issue continues
110+
111+
When you contact support, include:
112+
113+
- Electron, `@flashcatcloud/electron-sdk`, and `@flashcatcloud/browser-rum` versions
114+
- Bundler and module format
115+
- Main-process initialization options with the Client Token removed
116+
- Main-process and renderer console errors
117+
- Failed request URL, status code, and error type
118+
119+
Do not send Client Tokens, server-side keys, or data that contains user-sensitive information.

0 commit comments

Comments
 (0)