Send Electron crashpad reports to Sentry from Nightly (#579)

* Send Electron crashpad reports to Sentry from Nightly

* Update electron-main.ts

* Increase timeout

* Fix preload injection breaking things

* Iterate

* Iterate

* Iterate

* iterate
This commit is contained in:
Michael Telatynski
2023-03-16 10:31:06 +00:00
committed by GitHub
parent 3d578e815a
commit 8235275d2c
4 changed files with 149 additions and 39 deletions

View File

@@ -19,7 +19,8 @@ limitations under the License.
// Squirrel on windows starts the app with various flags as hooks to tell us when we've been installed/uninstalled etc.
import "./squirrelhooks";
import { app, BrowserWindow, Menu, autoUpdater, protocol, dialog } from "electron";
import { app, BrowserWindow, Menu, autoUpdater, protocol, dialog, Input } from "electron";
import * as Sentry from "@sentry/electron/main";
import AutoLaunch from "auto-launch";
import path from "path";
import windowStateKeeper from "electron-window-state";
@@ -38,18 +39,11 @@ import webContentsHandler from "./webcontents-handler";
import * as updater from "./updater";
import { getProfileFromDeeplink, protocolInit } from "./protocol";
import { _t, AppLocalization } from "./language-helper";
import Input = Electron.Input;
const argv = minimist(process.argv, {
alias: { help: "h" },
});
// Things we need throughout the file but need to be created
// async to are initialised in setupGlobals()
let asarPath: string;
let resPath: string;
let iconPath: string;
if (argv["help"]) {
console.log("Options:");
console.log(" --profile-dir {path}: Path to where to store the profile.");
@@ -119,28 +113,32 @@ async function tryPaths(name: string, root: string, rawPaths: string[]): Promise
const homeserverProps = ["default_is_url", "default_hs_url", "default_server_name", "default_server_config"] as const;
// Find the webapp resources and set up things that require them
async function setupGlobals(): Promise<void> {
// find the webapp asar.
asarPath = await tryPaths("webapp", __dirname, [
// If run from the source checkout, this will be in the directory above
"../webapp.asar",
// but if run from a packaged application, electron-main.js will be in
// a different asar file so it will be two levels above
"../../webapp.asar",
// also try without the 'asar' suffix to allow symlinking in a directory
"../webapp",
// from a packaged application
"../../webapp",
]);
let asarPathPromise: Promise<string> | undefined;
// Get the webapp resource file path, memoizes result
function getAsarPath(): Promise<string> {
if (!asarPathPromise) {
asarPathPromise = tryPaths("webapp", __dirname, [
// If run from the source checkout, this will be in the directory above
"../webapp.asar",
// but if run from a packaged application, electron-main.js will be in
// a different asar file, so it will be two levels above
"../../webapp.asar",
// also try without the 'asar' suffix to allow symlinking in a directory
"../webapp",
// from a packaged application
"../../webapp",
]);
}
// we assume the resources path is in the same place as the asar
resPath = await tryPaths("res", path.dirname(asarPath), [
// If run from the source checkout
"res",
// if run from packaged application
"",
]);
return asarPathPromise;
}
// Loads the config from asar, and applies a config.json from userData atop if one exists
// Writes config to `global.vectorConfig`. Does nothing if `global.vectorConfig` is already set.
async function loadConfig(): Promise<void> {
if (global.vectorConfig) return;
const asarPath = await getAsarPath();
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
@@ -168,7 +166,7 @@ async function setupGlobals(): Promise<void> {
.reduce((obj, key) => {
obj[key] = global.vectorConfig[key];
return obj;
}, {} as Omit<Partial<typeof global["vectorConfig"]>, keyof typeof homeserverProps>);
}, {} as Omit<Partial<(typeof global)["vectorConfig"]>, keyof typeof homeserverProps>);
}
global.vectorConfig = Object.assign(global.vectorConfig, localConfig);
@@ -186,13 +184,41 @@ async function setupGlobals(): Promise<void> {
// Could not load local config, this is expected in most cases.
}
}
// Configure Electron Sentry and crashReporter using sentry.dsn in config.json if one is present.
async function configureSentry(): Promise<void> {
await loadConfig();
const { dsn, environment } = global.vectorConfig.sentry || {};
if (dsn) {
console.log(`Enabling Sentry with dsn=${dsn} environment=${environment}`);
Sentry.init({
dsn,
environment,
// We don't actually use this IPC, but we do not want Sentry injecting preloads
ipcMode: Sentry.IPCMode.Classic,
});
}
}
// Set up globals for Tray and AutoLaunch
async function setupGlobals(): Promise<void> {
const asarPath = await getAsarPath();
await loadConfig();
// we assume the resources path is in the same place as the asar
const resPath = await tryPaths("res", path.dirname(asarPath), [
// If run from the source checkout
"res",
// if run from packaged application
"",
]);
// The tray icon
// It's important to call `path.join` so we don't end up with the packaged asar in the final path.
const iconFile = `element.${process.platform === "win32" ? "ico" : "png"}`;
iconPath = path.join(resPath, "img", iconFile);
global.trayConfig = {
icon_path: iconPath,
icon_path: path.join(resPath, "img", iconFile),
brand: global.vectorConfig.brand || "Element",
};
@@ -206,9 +232,9 @@ async function setupGlobals(): Promise<void> {
});
}
// Look for an auto-launcher under 'Riot' and if we find one,
// port its enabled/disabled-ness over to the new 'Element' launcher
async function moveAutoLauncher(): Promise<void> {
// Look for an auto-launcher under 'Riot' and if we find one, port it's
// enabled/disabled-ness over to the new 'Element' launcher
if (!global.vectorConfig.brand || global.vectorConfig.brand === "Element") {
const oldLauncher = new AutoLaunch({
name: "Riot",
@@ -261,6 +287,8 @@ const warnBeforeExit = (event: Event, input: Input): void => {
}
};
configureSentry();
// handle uncaught errors otherwise it displays
// stack traces in popup dialogs, which is terrible (which
// it will do any time the auto update poke fails, and there's
@@ -322,7 +350,10 @@ if (global.store.get("disableHardwareAcceleration", false) === true) {
}
app.on("ready", async () => {
let asarPath: string;
try {
asarPath = await getAsarPath();
await setupGlobals();
await moveAutoLauncher();
} catch (e) {
@@ -422,7 +453,7 @@ app.on("ready", async () => {
// https://www.electronjs.org/docs/faq#the-font-looks-blurry-what-is-this-and-what-can-i-do
backgroundColor: "#fff",
icon: iconPath,
icon: global.trayConfig.icon_path,
show: false,
autoHideMenuBar: global.store.get("autoHideMenuBar", true),