From 3e43757b017ab148637d57066da0d56d68ae6b41 Mon Sep 17 00:00:00 2001 From: "Hung-Han (Henry) Chen" Date: Thu, 8 Jul 2021 10:15:45 +0300 Subject: [PATCH] Refactor into SentryInit(), add try...catch block for Sentry.init and others Signed-off-by: Hung-Han (Henry) Chen --- src/common/sentry.ts | 105 ++++++++++++++++++++++++++++++++++++++ src/main/index.ts | 30 ++--------- src/renderer/lens-app.tsx | 30 +---------- 3 files changed, 110 insertions(+), 55 deletions(-) create mode 100644 src/common/sentry.ts diff --git a/src/common/sentry.ts b/src/common/sentry.ts new file mode 100644 index 0000000000..140da033f6 --- /dev/null +++ b/src/common/sentry.ts @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import { CaptureConsole, Dedupe, Offline } from "@sentry/integrations"; +import { sentryDsn, sentryDsnIsValid, isProduction } from "./vars"; +import { UserStore } from "./user-store"; +import logger from "../main/logger"; + +// https://www.electronjs.org/docs/api/process#processtype-readonly +const electronProcessType = ["browser", "renderer", "worker"] as const; +const integrations = [ + new CaptureConsole({ levels: ["error"] }), + new Dedupe(), + new Offline() +]; +const initialScope = (processType: typeof electronProcessType[number]) => { + return { + tags: { + // "translate" browser to 'main' as Lens developer more familiar with the term 'main' + "process": processType === "browser" ? "main" : "renderer" + } + }; +}; + +const environment = isProduction ? "production" : "development"; + +const logInitError = (reason: string) => { + logger.error(`⚠️ [SENTRY-INIT]: ${reason}, Sentry is not initialized.`); +}; + +export const SentryInit = () => { + if (!sentryDsnIsValid) { + logInitError("Sentry DSN is not valid"); + + return; + } + + const processType = process.type as typeof electronProcessType[number]; + + let Sentry; + + try { + // if in main process + if (processType === "browser") { + Sentry = require("@sentry/electron/dist/main"); + } + + // if in renderer process + if (processType === "renderer") { + Sentry = require("@sentry/electron/dist/renderer"); + } + } catch (error) { + logInitError(`Error loading Sentry module ${error?.message}`); + + return; + } + + + if (!Sentry) { + logInitError(`Unsupported process type ${processType}`); + + return; + } + + try { + Sentry.init({ + beforeSend(event: unknown) { + const allowErrorReporting = UserStore.getInstance().allowErrorReporting; + + if (allowErrorReporting) return event; + + logger.info(`🔒 [SENTRY-BEFORE-SEND-HOOK]: allowErrorReporting: ${allowErrorReporting}. Sentry event is caught but not sent to server.`); + logger.info(event); + + return null; + }, + dsn: sentryDsn, + integrations, + initialScope: initialScope(processType), + environment + }); + } catch (error) { + logInitError(`Sentry.init() error ${error?.message}`); + + return; + } +}; diff --git a/src/main/index.ts b/src/main/index.ts index 321cf37fb2..29b3798d7a 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -26,7 +26,7 @@ import * as Mobx from "mobx"; import * as LensExtensionsCommonApi from "../extensions/common-api"; import * as LensExtensionsMainApi from "../extensions/main-api"; import { app, autoUpdater, dialog, powerMonitor } from "electron"; -import { appName, isMac, productName, sentryDsn, sentryDsnIsValid, isProduction } from "../common/vars"; +import { appName, isMac, productName } from "../common/vars"; import path from "path"; import { LensProxy } from "./proxy/lens-proxy"; import { WindowManager } from "./window-manager"; @@ -59,33 +59,9 @@ import { UserStore } from "../common/user-store"; import { WeblinkStore } from "../common/weblink-store"; import { ExtensionsStore } from "../extensions/extensions-store"; import { FilesystemProvisionerStore } from "./extension-filesystem"; -import { CaptureConsole, Dedupe, Offline } from "@sentry/integrations"; -import * as Sentry from "@sentry/electron/dist/main"; - -if (sentryDsnIsValid) { - Sentry.init({ - beforeSend(event) { - const allow = UserStore.getInstance().allowErrorReporting; - - if (allow) return event; - - return null; - }, - dsn: sentryDsn, - integrations: [ - new CaptureConsole({ levels: ["error"] }), - new Dedupe(), - new Offline() - ], - initialScope: { - tags: { - "process": "main" - } - }, - environment: isProduction ? "production" : "development" - }); -} +import { SentryInit } from "../common/sentry"; +SentryInit(); const workingDir = path.join(app.getPath("appData"), appName); const cleanup = disposer(); diff --git a/src/renderer/lens-app.tsx b/src/renderer/lens-app.tsx index a34f4c6bd0..cbe0d27f6d 100644 --- a/src/renderer/lens-app.tsx +++ b/src/renderer/lens-app.tsx @@ -36,35 +36,9 @@ import { registerIpcHandlers } from "./ipc"; import { ipcRenderer } from "electron"; import { IpcRendererNavigationEvents } from "./navigation/events"; import { catalogEntityRegistry } from "./api/catalog-entity-registry"; -import { sentryDsn, sentryDsnIsValid, isProduction } from "../common/vars"; -import { CaptureConsole, Dedupe, Offline } from "@sentry/integrations"; -import * as Sentry from "@sentry/electron/dist/renderer"; -import { UserStore } from "../common/user-store"; - -if (sentryDsnIsValid) { - Sentry.init({ - beforeSend(event) { - const allow = UserStore.getInstance().allowErrorReporting; - - if (allow) return event; - - return null; - }, - dsn: sentryDsn, - integrations: [ - new CaptureConsole({ levels: ["error"] }), - new Dedupe(), - new Offline() - ], - initialScope: { - tags: { - "process": "renderer" - } - }, - environment: isProduction ? "production" : "development" - }); -} +import { SentryInit } from "../common/sentry"; +SentryInit(); @observer export class LensApp extends React.Component {