Electron
Electron is a framework for building desktop applications using JavaScript, HTML, and CSS. Learn how to set it up with Sentry.
@sentry/electron
is the official Sentry SDK for Electron applications. It can capture JavaScript exceptions in the main
and renderer
processes, as well as collect native crash reports (Minidumps).
npm install --save @sentry/electron
You should init
the SDK in the main
process and every renderer
process you spawn.
In the Electron main
process:
import * as Sentry from "@sentry/electron/main";
Sentry.init({
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
});
In the Electron renderer
process:
import * as Sentry from "@sentry/electron/renderer";
Sentry.init({
integrations: [
Sentry.browserTracingIntegration(),
Sentry.replayIntegration(),
],
// Set tracesSampleRate to 1.0 to capture 100%
// of transactions for performance monitoring.
// We recommend adjusting this value in production
tracesSampleRate: 1.0,
// Capture Replay for 10% of all sessions,
// plus for 100% of sessions with an error
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
});
Once configured, all unhandled exceptions and native crashes are automatically captured by Sentry.
Important: Note your DSN. The DSN (Data Source Name) tells the SDK where to send events. If you forget it, view Settings -> Projects -> Client Keys (DSN) in the Sentry web UI.
Our Sentry Wizard can help with the setup process. Make sure you have installed the @sentry/wizard
npm package globally, then run:
npm install -g @sentry/wizard
sentry-wizard --integration electron
This will guide you through the installation and configuration process and suggest useful tools for development. If you instead prefer to setup manually, keep reading.
Start by configuring the SDK as described above. This will enable the Electron CrashReporter for native app crashes and capture any uncaught JavaScript exceptions using the JavaScript SDKs under the hood. Be sure to call this function as early as possible in the main
process and all renderer
processes to also catch errors during startup.
If you are using preload scripts, have contextIsolation
enabled and want to capture errors from the isolated preload context, you should call the renderer init
early in that context too.
If you change the userData
directory used by your app, ensure this change is made before you configure the SDK as this path is used to cache scope and events between application restarts.
import { app } from "electron";
import * as Sentry from "@sentry/electron/main";
app.setPath("userData", "~/.config/my-app");
Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0" });
If you're using a framework-specific Sentry SDK in the Electron renderers, you can pass that init
function as the second parameter and the two SDKs functionalities will be combined:
import { init } from "@sentry/electron/renderer";
import { init as reactInit } from "@sentry/react";
init(
{
/* config */
},
reactInit,
);
The default transport automatically handles offline events caching from both the main and renderer processes. Following, are a number of options that allow you to customize queueing behavior:
import * as Sentry from "@sentry/electron/main";
Sentry.init({
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
transportOptions: {
/* The maximum number of days to keep an event in the queue. */
maxQueueAgeDays: 30,
/* The maximum number of events to keep in the queue. */
maxQueueCount: 30,
/**
* Called before we attempt to send an envelope to Sentry.
*
* If this function returns false, `shouldStore` will be called to determine if the envelope should be stored.
*
* Default: () => true
*
* @param envelope The envelope that will be sent.
* @returns Whether we should attempt to send the envelope
*/
shouldSend: (envelope: Envelope) => boolean | Promise<boolean>;
/**
* Called before an event is stored.
*
* Return false to drop the envelope rather than store it.
*
* Default: () => true
*
* @param envelope The envelope that failed to send.
* @param error The error that occurred.
* @param retryDelay The current retry delay in milliseconds.
* @returns Whether we should store the envelope in the queue
*/
shouldStore: (envelope: Envelope, error: Error, retryDelay: number) => boolean | Promise<boolean>;
},
});
To give the most detailed context for all events including native crashes, the SDK merges context, scope and breadcrumbs from all processes in the Electron main
process.
By default, the SDK attempts to establish communication from renderer
to main
via Electron IPC API's and if that fails, falls back to using a custom HTTP protocol. You can change this default via the ipcMode
option which can be one of Classic
, Protocol
or Both
.
const { init, IPCMode } = require("@sentry/electron/main");
init({
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
debug: true,
ipcMode: IPCMode.Protocol,
});
The SDK attempts to inject a preload script via session.setPreloads(preloads)
and by default only does this for the defaultSession
. If you are using other sessions, you can pass custom sessions via the getSessions
option in the main
process:
import { session } from "electron";
import * as Sentry from "@sentry/electron/main";
Sentry.init({
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
getSessions: () => [
session.defaultSession,
session.fromPartition("persist:my-session"),
],
});
If your app bundles the main
process JavaScript, the SDK cannot automatically inject preload scripts because the script will be missing from the packaged app. In this case, the SDK will send events and scope updates via a custom HTTP protocol and window.fetch
.
If you would like to manually bundle and configure the preload script, you should import the SDK preload code into your own preload script:
import "@sentry/electron/preload";
This script exposes IPC to the isolated renderer via Electrons contextBridge
API.
Check out the example apps for how to do this.
To get symbolicated stack traces for native crashes, you should enable fetching debug symbols from the Electron symbol server. Go to Project Settings > Debug Files and add Electron to the list of built-in repositories.
If your app uses a custom Electron fork, contains modules with native extensions or spawns subprocesses, you should upload those symbols manually using the Sentry CLI. For more information, see Native Usage.
Known Issue
It is currently not possible to send events from native code (such as a C++ extension). However, crashes will still be reported to Sentry if they happen in a process where the SDK has been configured. Also, crash reports from sub processes will not be reported automatically on all platforms. This feature will be added in a future SDK update.
The Electron SDK supports Source Maps. If you upload source maps in addition to your minified files that data becomes available in Sentry. For more information see Source Maps.
Sentry can process Minidumps created when any of the Electron processes crash. To do so, the SDK needs to upload those files once the application restarts (or immediately for renderer crashes). All event meta data including user information and breadcrumbs are included in these uploads.
Due to restrictions of macOS app sandboxing, native crashes cannot be collected in Mac App Store builds. In this case, native crash handling will be disabled.
A Word on Data Privacy
Minidumps are memory dumps of the process at the moment it crashes. As such, they might contain sensitive information on the target system, such as environment variables, local path names or maybe even in-memory representations of input fields including passwords. Sentry does not store these memory dumps. Once processed, they are removed immediately and all sensitive information is stripped from the resulting issues.
To allow Sentry to fully process native crashes and provide you with symbolicated stack traces, you need to upload Debug Information Files (sometimes also referred to as Debug Symbols or just Symbols).
First, make sure that the Electron Symbol Server is enabled for your project. Go to Project Settings > Debug Files and choose Electron
from the list of Builtin Repositories. You can add more symbol servers for the platforms you are deploying to, depending on your needs.
If your application contains custom native extensions or you wish to symbolicate crashes from a spawned child process, upload their debug information manually during your build or release process. See Debug Information Files for a detailed description of how to set up Sentry for native development. Additionally, see Uploading Debug Information for the upload process.
The SDK relies on the Electron CrashReporter to generate the crash dumps. To receive crash reports for child processes, you need to make sure the crash reporter is activated by either the SDK or manually (see below).
An exception to this is macOS, where the crash reporter only needs to be started in the main
process and watches all its child processes. The SDK already takes care of this difference, so there is no need to manually disable enableNative
.
For custom child processes, especially ones not written in JavaScript, you need to integrate a library that can generate Minidumps. These are most notably Crashpad and Breakpad. Please refer to their respective documentation on how to build and integrate them. Configure them with the following upload URL:
https://o0.ingest.sentry.io/api/0/minidump/?sentry_key=examplePublicKey
It currently not possible create breadcrumbs or other event meta data from native code. This has to happen in JavaScript. Support for this is planned in future releases.
You can also capture native crashes by starting the Electron CrashReporter manually. Sentry is able to provide symbolicated stack traces and show system information, but no Electron-specific metadata, breadcrumbs or context information will be present. This is useful in cases where you cannot use the full Electron SDK:
const { crashReporter } = require("electron");
crashReporter.start({
companyName: "YourCompany",
productName: "YourApp",
ignoreSystemCrashHandler: true,
submitURL: "https://o0.ingest.sentry.io/api/0/minidump/?sentry_key=examplePublicKey",
});
To find out why Sentry needs your source maps and how to provide them visit: Source Maps
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").