mirror of
				https://github.com/zulip/zulip-desktop.git
				synced 2025-11-04 05:53:21 +00:00 
			
		
		
		
	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:
		@@ -1,6 +1,7 @@
 | 
			
		||||
import fs from "fs";
 | 
			
		||||
import path from "path";
 | 
			
		||||
 | 
			
		||||
import * as Sentry from "@sentry/electron";
 | 
			
		||||
import {JsonDB} from "node-json-db";
 | 
			
		||||
import {DataError} from "node-json-db/dist/lib/Errors";
 | 
			
		||||
import type * as z from "zod";
 | 
			
		||||
@@ -91,7 +92,7 @@ function reloadDB(): void {
 | 
			
		||||
      );
 | 
			
		||||
      logger.error("Error while JSON parsing settings.json: ");
 | 
			
		||||
      logger.error(error);
 | 
			
		||||
      logger.reportSentry(error);
 | 
			
		||||
      Sentry.captureException(error);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,9 @@
 | 
			
		||||
import {Console} from "console"; // eslint-disable-line node/prefer-global/console
 | 
			
		||||
import electron from "electron";
 | 
			
		||||
import fs from "fs";
 | 
			
		||||
import os from "os";
 | 
			
		||||
 | 
			
		||||
import {initSetUp} from "./default-util";
 | 
			
		||||
import {app} from "./remote";
 | 
			
		||||
import {captureException, sentryInit} from "./sentry-util";
 | 
			
		||||
 | 
			
		||||
interface LoggerOptions {
 | 
			
		||||
  file?: string;
 | 
			
		||||
@@ -13,24 +11,6 @@ interface LoggerOptions {
 | 
			
		||||
 | 
			
		||||
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`;
 | 
			
		||||
 | 
			
		||||
type Level = "log" | "debug" | "info" | "warn" | "error";
 | 
			
		||||
@@ -91,12 +71,6 @@ export default class Logger {
 | 
			
		||||
    return timestamp;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  reportSentry(error: unknown): void {
 | 
			
		||||
    if (reportErrors) {
 | 
			
		||||
      captureException(error);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async trimLog(file: string): Promise<void> {
 | 
			
		||||
    const data = await fs.promises.readFile(file, "utf8");
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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";
 | 
			
		||||
@@ -5,7 +5,6 @@ export interface MainMessage {
 | 
			
		||||
  "clear-app-settings": () => void;
 | 
			
		||||
  "configure-spell-checker": () => void;
 | 
			
		||||
  downloadFile: (url: string, downloadPath: string) => void;
 | 
			
		||||
  "error-reporting": () => void;
 | 
			
		||||
  "fetch-user-agent": () => string;
 | 
			
		||||
  "focus-app": () => void;
 | 
			
		||||
  "focus-this-webview": () => void;
 | 
			
		||||
@@ -39,7 +38,6 @@ export interface RendererMessage {
 | 
			
		||||
  downloadFileCompleted: (filePath: string, fileName: string) => void;
 | 
			
		||||
  downloadFileFailed: (state: string) => void;
 | 
			
		||||
  "enter-fullscreen": () => void;
 | 
			
		||||
  "error-reporting-val": (errorReporting: boolean) => void;
 | 
			
		||||
  focus: () => void;
 | 
			
		||||
  "focus-webview-with-id": (webviewId: number) => void;
 | 
			
		||||
  forward: () => void;
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,6 @@ import * as remoteMain from "@electron/remote/main";
 | 
			
		||||
import windowStateKeeper from "electron-window-state";
 | 
			
		||||
 | 
			
		||||
import * as ConfigUtil from "../common/config-util";
 | 
			
		||||
import {sentryInit} from "../common/sentry-util";
 | 
			
		||||
import type {RendererMessage} from "../common/typed-ipc";
 | 
			
		||||
import type {MenuProps} from "../common/types";
 | 
			
		||||
 | 
			
		||||
@@ -14,11 +13,15 @@ import {appUpdater} from "./autoupdater";
 | 
			
		||||
import * as BadgeSettings from "./badge-settings";
 | 
			
		||||
import * as AppMenu from "./menu";
 | 
			
		||||
import {_getServerSettings, _isOnline, _saveServerIcon} from "./request";
 | 
			
		||||
import {sentryInit} from "./sentry";
 | 
			
		||||
import {setAutoLaunch} from "./startup";
 | 
			
		||||
import {ipcMain, send} from "./typed-ipc-main";
 | 
			
		||||
 | 
			
		||||
const {GDK_BACKEND} = process.env;
 | 
			
		||||
 | 
			
		||||
// Initialize sentry for main process
 | 
			
		||||
sentryInit();
 | 
			
		||||
 | 
			
		||||
let mainWindowState: windowStateKeeper.State;
 | 
			
		||||
 | 
			
		||||
// Prevent window being garbage collected
 | 
			
		||||
@@ -199,12 +202,6 @@ function createMainWindow(): Electron.BrowserWindow {
 | 
			
		||||
    mainWindow.setMenuBarVisibility(!shouldHideMenu);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Initialize sentry for main process
 | 
			
		||||
  const errorReporting = ConfigUtil.getConfigItem("errorReporting", true);
 | 
			
		||||
  if (errorReporting) {
 | 
			
		||||
    sentryInit();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const page = mainWindow.webContents;
 | 
			
		||||
 | 
			
		||||
  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(
 | 
			
		||||
    "save-last-tab",
 | 
			
		||||
    (_event: Electron.IpcMainEvent, index: number) => {
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import path from "path";
 | 
			
		||||
import stream from "stream";
 | 
			
		||||
import util from "util";
 | 
			
		||||
 | 
			
		||||
import * as Sentry from "@sentry/electron";
 | 
			
		||||
import getStream from "get-stream";
 | 
			
		||||
import * as z from "zod";
 | 
			
		||||
 | 
			
		||||
@@ -103,7 +104,7 @@ export const _saveServerIcon = async (
 | 
			
		||||
  } catch (error: unknown) {
 | 
			
		||||
    logger.log("Could not get server icon.");
 | 
			
		||||
    logger.log(error);
 | 
			
		||||
    logger.reportSentry(error);
 | 
			
		||||
    Sentry.captureException(error);
 | 
			
		||||
    return defaultIconUrl;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										22
									
								
								app/main/sentry.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								app/main/sentry.ts
									
									
									
									
									
										Normal 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
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
@@ -3,6 +3,7 @@ import path from "path";
 | 
			
		||||
 | 
			
		||||
import {Menu, app, dialog, session} from "@electron/remote";
 | 
			
		||||
import * as remote from "@electron/remote";
 | 
			
		||||
import * as Sentry from "@sentry/electron";
 | 
			
		||||
 | 
			
		||||
import type {Config} 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 ReconnectUtil from "./utils/reconnect-util";
 | 
			
		||||
 | 
			
		||||
Sentry.init({});
 | 
			
		||||
 | 
			
		||||
type WebviewListener =
 | 
			
		||||
  | "webview-reload"
 | 
			
		||||
  | "back"
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ import fs from "fs";
 | 
			
		||||
import path from "path";
 | 
			
		||||
 | 
			
		||||
import {app, dialog} from "@electron/remote";
 | 
			
		||||
import * as Sentry from "@sentry/electron";
 | 
			
		||||
import {JsonDB} from "node-json-db";
 | 
			
		||||
import {DataError} from "node-json-db/dist/lib/Errors";
 | 
			
		||||
import * as z from "zod";
 | 
			
		||||
@@ -148,7 +149,7 @@ export async function updateSavedServer(
 | 
			
		||||
  } catch (error: unknown) {
 | 
			
		||||
    logger.log("Could not update server icon.");
 | 
			
		||||
    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);
 | 
			
		||||
      logger.reportSentry(error);
 | 
			
		||||
      Sentry.captureException(error);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user