{% hint style="info" %} Want to see a sample Electron application integrated with BugSplat? Check out my-electron-crasher! {% endhint %}
BugSplat supports the collection of both electron.crashReporter (native) and node.js crash reports. Native crashes are generated via Crashpad and BugSplat requires symbol files in order to calculate the call stack.
BugSplat will automatically resolve Electron framework symbol files when calculating call stacks. However, if your application includes native add-ons or is packaged with electron-builder you will need to upload application-specific symbol files to see full native call stacks. All symbol files must be uploaded to BugSplat via @bugsplat/symbol-upload, symupload, or manually via the Versions page. More information about uploading symbol files to BugSplat can be found here.
BugSplat-node can also be used to collect uncaughtException and unhandledRejection events in your application's JavaScript code.
Configure electron.crashReporter to upload crash reports to BugSplat using the following steps. BugSplat will automatically download Electron and Electron Framework symbol files. If your application uses Native Node Modules, you will need to generate and upload symbol files to resolve call stacks correctly.
Add a database
property with the value of your BugSplat database to package.json
. Be sure to replace your-bugsplat-database
with the actual value of your BugSplat database.
{
...
"database": "your-bugsplat-database"
}
Next, call crashReporter.start
as shown in the example below. You may optionally pass globalExtra values for key
, email
, comments
, notes
, and ipAddress
.
Note that the globalExtra
fields will be sent with crashes captured on all processes:
const { crashReporter } = require("electron");
const { database, name, version } = require("../../package.json");
crashReporter.start({
submitURL: `https://${database}.bugsplat.com/post/electron/v2/crash.php`,
ignoreSystemCrashHandler: true,
uploadToServer: true,
rateLimit: false,
globalExtra: {
"product": name,
"version": version,
"key": "en-US",
"email": "[email protected]",
"comments": "BugSplat rocks!",
}
})
For more information on configuring electron.crashReporter
including adding properties to individual processes, please see the Electron crashReporter documentation.
Generate a crash in one of the Electron processes to test your BugSplat integration:
process.crash()
Navigate to the Crashes page in BugSplat. You should see a new crash report for your application. Click the link in the ID column to see details about your crash on the Crash page:
Electron Native Crashes
Electron Native Crash
If your application uses a node native addon, you must generate and upload symbols for each binary and for every build.
Use @bugsplat/symbol-upload and the -m
argument to generate and upload .sym
files from your application binaries automatically. You can run symbol-upload without any arguments to view all available options.
npx symbol-upload -u [email protected] -p password -d ./dist -f "**/*.node" -m
Alternatively, you can add a build step to generate and upload .sym
files for your node native addon using standard Breakpad tools. To generate symbol files, you can run dump_syms with a path to a .node
file after the Node Native Module build or rebuild step if you're using a tool like electron-rebuild. Once you've generated a .sym
file for your .node
native module, the .sym
file can be uploaded via symupload, or manually on the Versions page.
Verify that your node native addon .sym
files show up on the Versions page. Be sure to upload symbols for each released version of your application. Integrate @bugsplat/symbol-upload or symupload into your build and release processes for best results.
To configure reporting of JavaScript or TypeScript errors in your main and renderer processes, please see our node.js documentation for installing and configuring bugsplat-node.
{% content-ref url="node.js.md" %} node.js.md {% endcontent-ref %}
Install bugsplat-node via the following command:
npm i bugsplat-node
Next import
or require
BugSplat in both your main and renderer threads.
import { BugSplatNode as BugSplat } from "bugsplat-node"
const bugsplat = new BugSplat(database, name, version)
In addition to the configuration demonstrated above, there are a few public methods that can be used to customize your BugSplat integration:
bugsplat.setDefaultAppKey(appKey); // Additional metadata that can be queried via BugSplat's web application
bugsplat.setDefaultUser(user); // The name or id of your user
bugsplat.setDefaultEmail(email); // The email of your user
bugsplat.setDefaultDescription(description); // A description placeholder that can be overridden at crash time
bugsplat.setDefaultAdditionalFilePaths([paths]); // Paths to files to be sent to BugSplat at post time (limit 1MB)
bugsplat.postAndExit(error, options); // Wrapper for post that calls process.exit(1) after posting error to BugSplat
bugsplat.post(error, options); // Aysnc function that posts an arbitrary Error object to BugSplat
// If the values options.appKey, options.user, options.email, options.description, options.additionalFilePaths are set the corresponding default values will be overwritten
// Returns a promise that resolves with properties: error (if there was an error posting to BugSplat), response (the response from the BugSplat crash post API), and original (the error passed by bugsplat.post)
Create an error handler for uncaughtExceptions
and unhandledPromise
rejections. We recommend you quit your application in the event of an uncaughtException
or unhandledPromiseRejection
. You may also want to add code to display a message to your user here:
const javaScriptErrorHandler = async (error) => {
await bugsplat.post(error);
app.quit();
}
Add the error handler created above to uncaughtException
and unhandledPromiseRejection
events:
process.on('unhandledRejection', javaScriptErrorHandler)
process.on('uncaughtException', javaScriptErrorHandler)
Many Electron applications run multiple node.js processes. For instance, the electron-quick-start application runs both a main and a renderer process. You must require bugsplat
in each process you want to capture errors. To capture errors in the renderer process, add the following to renderer.js:
Reloading or quitting the application is sometimes desirable when an error occurs in the renderer process. The following is an example of how to invoke the main process from the renderer and quit your application in the case of an unhandled exception in the renderer:
window.onerror = async (messageOrEvent, source, lineno, colno, error) => {
await bugsplat.post(error)
ipcRenderer.send('rendererCrash')
}
import { ipcMain } from "electron";
ipcMain.on('rendererCrash', function () {
// Display an error and reload or quit the app here
})
Test BugSplat by throwing a new error in either the main or renderer process:
throw new Error("BugSplat!");
If you're using TypeScript or another language that compiles to JavaScript, BugSplat can map uglified and minified JavaScript function names, file names, and line numbers back to their original values via source maps.
To upload source maps, add a symbol-upload script that uploads all your build's .js.map
files:
{
...
"scripts": {
"upload-source-maps": "npx symbol-upload -u [email protected] -p password -d ./dist -f \"**/*.js.map\""
}
}
Run your application and generate an error report. Navigate to the Crashes page in BugSplat to view reports for the application you just configured. Click the link in the ID column to see details about your crash on the Crash page:
TypeScrpt Error on Crashes Page
TypeScript Error in Main Process
That’s it! Your Electron application is now configured to upload crash reports to BugSplat.
BugSplat loves open-source software! If you have suggestions on how we can improve this integration, please reach out to [email protected], create an issue in our GitHub repo or send us a pull request.