Untangle Sentry initialization.

Thanks to upstream for the helpful advice at
https://github.com/getsentry/sentry-electron/issues/427.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg
2022-03-07 12:05:21 -08:00
parent 9c1f47badd
commit e434c5b5d0
9 changed files with 36 additions and 63 deletions

View File

@@ -1,6 +1,7 @@
import fs from "fs"; import fs from "fs";
import path from "path"; import path from "path";
import * as Sentry from "@sentry/electron";
import {JsonDB} from "node-json-db"; import {JsonDB} from "node-json-db";
import {DataError} from "node-json-db/dist/lib/Errors"; import {DataError} from "node-json-db/dist/lib/Errors";
import type * as z from "zod"; import type * as z from "zod";
@@ -91,7 +92,7 @@ function reloadDB(): void {
); );
logger.error("Error while JSON parsing settings.json: "); logger.error("Error while JSON parsing settings.json: ");
logger.error(error); logger.error(error);
logger.reportSentry(error); Sentry.captureException(error);
} }
} }

View File

@@ -1,11 +1,9 @@
import {Console} from "console"; // eslint-disable-line node/prefer-global/console import {Console} from "console"; // eslint-disable-line node/prefer-global/console
import electron from "electron";
import fs from "fs"; import fs from "fs";
import os from "os"; import os from "os";
import {initSetUp} from "./default-util"; import {initSetUp} from "./default-util";
import {app} from "./remote"; import {app} from "./remote";
import {captureException, sentryInit} from "./sentry-util";
interface LoggerOptions { interface LoggerOptions {
file?: string; file?: string;
@@ -13,24 +11,6 @@ interface LoggerOptions {
initSetUp(); initSetUp();
let reportErrors = true;
if (process.type === "renderer") {
// Report Errors to Sentry only if it is enabled in settings
// Gets the value of reportErrors from config-util for renderer process
// For main process, sentryInit() is handled in index.js
const {ipcRenderer} = electron;
ipcRenderer.send("error-reporting");
ipcRenderer.on(
"error-reporting-val",
(_event: Event, errorReporting: boolean) => {
reportErrors = errorReporting;
if (reportErrors) {
sentryInit();
}
},
);
}
const logDir = `${app.getPath("userData")}/Logs`; const logDir = `${app.getPath("userData")}/Logs`;
type Level = "log" | "debug" | "info" | "warn" | "error"; type Level = "log" | "debug" | "info" | "warn" | "error";
@@ -91,12 +71,6 @@ export default class Logger {
return timestamp; return timestamp;
} }
reportSentry(error: unknown): void {
if (reportErrors) {
captureException(error);
}
}
async trimLog(file: string): Promise<void> { async trimLog(file: string): Promise<void> {
const data = await fs.promises.readFile(file, "utf8"); const data = await fs.promises.readFile(file, "utf8");

View File

@@ -1,18 +0,0 @@
import {init} from "@sentry/electron";
import {app} from "./remote";
export const sentryInit = (): void => {
if (app.isPackaged) {
init({
dsn: "https://628dc2f2864243a08ead72e63f94c7b1@sentry.io/204668",
// We should ignore this error since it's harmless and we know the reason behind this
// This error mainly comes from the console logs.
// This is a temp solution until Sentry supports disabling the console logs
ignoreErrors: ["does not appear to be a valid Zulip server"],
/// sendTimeout: 30 // wait 30 seconds before considering the sending capture to have failed, default is 1 second
});
}
};
export {captureException} from "@sentry/electron";

View File

@@ -5,7 +5,6 @@ export interface MainMessage {
"clear-app-settings": () => void; "clear-app-settings": () => void;
"configure-spell-checker": () => void; "configure-spell-checker": () => void;
downloadFile: (url: string, downloadPath: string) => void; downloadFile: (url: string, downloadPath: string) => void;
"error-reporting": () => void;
"fetch-user-agent": () => string; "fetch-user-agent": () => string;
"focus-app": () => void; "focus-app": () => void;
"focus-this-webview": () => void; "focus-this-webview": () => void;
@@ -39,7 +38,6 @@ export interface RendererMessage {
downloadFileCompleted: (filePath: string, fileName: string) => void; downloadFileCompleted: (filePath: string, fileName: string) => void;
downloadFileFailed: (state: string) => void; downloadFileFailed: (state: string) => void;
"enter-fullscreen": () => void; "enter-fullscreen": () => void;
"error-reporting-val": (errorReporting: boolean) => void;
focus: () => void; focus: () => void;
"focus-webview-with-id": (webviewId: number) => void; "focus-webview-with-id": (webviewId: number) => void;
forward: () => void; forward: () => void;

View File

@@ -6,7 +6,6 @@ import * as remoteMain from "@electron/remote/main";
import windowStateKeeper from "electron-window-state"; import windowStateKeeper from "electron-window-state";
import * as ConfigUtil from "../common/config-util"; import * as ConfigUtil from "../common/config-util";
import {sentryInit} from "../common/sentry-util";
import type {RendererMessage} from "../common/typed-ipc"; import type {RendererMessage} from "../common/typed-ipc";
import type {MenuProps} from "../common/types"; import type {MenuProps} from "../common/types";
@@ -14,11 +13,15 @@ import {appUpdater} from "./autoupdater";
import * as BadgeSettings from "./badge-settings"; import * as BadgeSettings from "./badge-settings";
import * as AppMenu from "./menu"; import * as AppMenu from "./menu";
import {_getServerSettings, _isOnline, _saveServerIcon} from "./request"; import {_getServerSettings, _isOnline, _saveServerIcon} from "./request";
import {sentryInit} from "./sentry";
import {setAutoLaunch} from "./startup"; import {setAutoLaunch} from "./startup";
import {ipcMain, send} from "./typed-ipc-main"; import {ipcMain, send} from "./typed-ipc-main";
const {GDK_BACKEND} = process.env; const {GDK_BACKEND} = process.env;
// Initialize sentry for main process
sentryInit();
let mainWindowState: windowStateKeeper.State; let mainWindowState: windowStateKeeper.State;
// Prevent window being garbage collected // Prevent window being garbage collected
@@ -199,12 +202,6 @@ function createMainWindow(): Electron.BrowserWindow {
mainWindow.setMenuBarVisibility(!shouldHideMenu); mainWindow.setMenuBarVisibility(!shouldHideMenu);
} }
// Initialize sentry for main process
const errorReporting = ConfigUtil.getConfigItem("errorReporting", true);
if (errorReporting) {
sentryInit();
}
const page = mainWindow.webContents; const page = mainWindow.webContents;
page.on("dom-ready", () => { page.on("dom-ready", () => {
@@ -460,12 +457,6 @@ ${error}`,
}, },
); );
// Using event.sender.send instead of page.send here to
// make sure the value of errorReporting is sent only once on load.
ipcMain.on("error-reporting", (event: Electron.IpcMainEvent) => {
send(event.sender, "error-reporting-val", errorReporting);
});
ipcMain.on( ipcMain.on(
"save-last-tab", "save-last-tab",
(_event: Electron.IpcMainEvent, index: number) => { (_event: Electron.IpcMainEvent, index: number) => {

View File

@@ -5,6 +5,7 @@ import path from "path";
import stream from "stream"; import stream from "stream";
import util from "util"; import util from "util";
import * as Sentry from "@sentry/electron";
import getStream from "get-stream"; import getStream from "get-stream";
import * as z from "zod"; import * as z from "zod";
@@ -103,7 +104,7 @@ export const _saveServerIcon = async (
} catch (error: unknown) { } catch (error: unknown) {
logger.log("Could not get server icon."); logger.log("Could not get server icon.");
logger.log(error); logger.log(error);
logger.reportSentry(error); Sentry.captureException(error);
return defaultIconUrl; return defaultIconUrl;
} }
}; };

22
app/main/sentry.ts Normal file
View File

@@ -0,0 +1,22 @@
import {app} from "electron";
import * as Sentry from "@sentry/electron";
import {getConfigItem} from "../common/config-util";
export const sentryInit = (): void => {
Sentry.init({
dsn: "https://628dc2f2864243a08ead72e63f94c7b1@sentry.io/204668",
// Don't report errors in development or if disabled by the user.
beforeSend: (event) =>
app.isPackaged && getConfigItem("errorReporting", true) ? event : null,
// We should ignore this error since it's harmless and we know the reason behind this
// This error mainly comes from the console logs.
// This is a temp solution until Sentry supports disabling the console logs
ignoreErrors: ["does not appear to be a valid Zulip server"],
/// sendTimeout: 30 // wait 30 seconds before considering the sending capture to have failed, default is 1 second
});
};

View File

@@ -3,6 +3,7 @@ import path from "path";
import {Menu, app, dialog, session} from "@electron/remote"; import {Menu, app, dialog, session} from "@electron/remote";
import * as remote from "@electron/remote"; import * as remote from "@electron/remote";
import * as Sentry from "@sentry/electron";
import type {Config} from "../../common/config-util"; import type {Config} from "../../common/config-util";
import * as ConfigUtil from "../../common/config-util"; import * as ConfigUtil from "../../common/config-util";
@@ -24,6 +25,8 @@ import * as DomainUtil from "./utils/domain-util";
import * as LinkUtil from "./utils/link-util"; import * as LinkUtil from "./utils/link-util";
import ReconnectUtil from "./utils/reconnect-util"; import ReconnectUtil from "./utils/reconnect-util";
Sentry.init({});
type WebviewListener = type WebviewListener =
| "webview-reload" | "webview-reload"
| "back" | "back"

View File

@@ -2,6 +2,7 @@ import fs from "fs";
import path from "path"; import path from "path";
import {app, dialog} from "@electron/remote"; import {app, dialog} from "@electron/remote";
import * as Sentry from "@sentry/electron";
import {JsonDB} from "node-json-db"; import {JsonDB} from "node-json-db";
import {DataError} from "node-json-db/dist/lib/Errors"; import {DataError} from "node-json-db/dist/lib/Errors";
import * as z from "zod"; import * as z from "zod";
@@ -148,7 +149,7 @@ export async function updateSavedServer(
} catch (error: unknown) { } catch (error: unknown) {
logger.log("Could not update server icon."); logger.log("Could not update server icon.");
logger.log(error); logger.log(error);
logger.reportSentry(error); Sentry.captureException(error);
} }
} }
@@ -170,7 +171,7 @@ function reloadDB(): void {
); );
logger.error("Error while JSON parsing domain.json: "); logger.error("Error while JSON parsing domain.json: ");
logger.error(error); logger.error(error);
logger.reportSentry(error); Sentry.captureException(error);
} }
} }