diff --git a/package.json b/package.json index 141ec3a5a0..47b3dc28dc 100644 --- a/package.json +++ b/package.json @@ -183,8 +183,6 @@ "@hapi/call": "^8.0.1", "@hapi/subtext": "^7.0.3", "@kubernetes/client-node": "^0.15.1", - "@sentry/electron": "^2.5.0", - "@sentry/integrations": "^6.10.0", "abort-controller": "^3.0.0", "array-move": "^3.0.1", "auto-bind": "^4.0.0", @@ -258,8 +256,6 @@ "@material-ui/icons": "^4.11.2", "@material-ui/lab": "^4.0.0-alpha.60", "@pmmmwh/react-refresh-webpack-plugin": "^0.4.3", - "@sentry/react": "^6.8.0", - "@sentry/types": "^6.8.0", "@testing-library/dom": "^8.2.0", "@testing-library/jest-dom": "^5.14.1", "@testing-library/react": "^11.2.6", diff --git a/src/common/logger-transports/index.ts b/src/common/logger-transports/index.ts deleted file mode 100644 index 6c7f04647b..0000000000 --- a/src/common/logger-transports/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * 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. - */ - -export * from "./sentry"; diff --git a/src/common/logger-transports/sentry.ts b/src/common/logger-transports/sentry.ts deleted file mode 100644 index bfcb7c4584..0000000000 --- a/src/common/logger-transports/sentry.ts +++ /dev/null @@ -1,76 +0,0 @@ -/** - * 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 Transport from "winston-transport"; -import { LEVEL } from "triple-beam"; -import { Severity } from "@sentry/browser"; -import * as Sentry from "@sentry/electron"; - -const SENTRY_LEVELS_MAP = { - silly: Severity.Debug, - verbose: Severity.Debug, - debug: Severity.Debug, - info: Severity.Info, - warn: Severity.Warning, - error: Severity.Error, -}; -const WINSTON_CMP: Record> = { - silly: new Set(["silly", "verbose", "debug", "info", "warn", "error"]), - verbose: new Set(["verbose", "debug", "info", "warn", "error"]), - debug: new Set(["debug", "info", "warn", "error"]), - info: new Set(["info", "warn", "error"]), - warn: new Set(["warn", "error"]), - error: new Set(["error"]), -}; - -export type WinstonLevel = keyof typeof SENTRY_LEVELS_MAP; - -export class SentryTransport extends Transport { - logLevels: Set; - - constructor(minWinstonLevel: WinstonLevel) { - super(); - - this.logLevels = WINSTON_CMP[minWinstonLevel]; - } - - log(info: any, next: () => void) { - setImmediate(() => { - this.emit("logged", info); - }); - - const { message, level: _, tags, user, ...extra } = info; - const winstonLevel: WinstonLevel = info[LEVEL]; - const level = SENTRY_LEVELS_MAP[winstonLevel]; - - try { - if (this.logLevels.has(winstonLevel)) { - Sentry.captureMessage(message, { - level, - tags, - extra, - }); - } - } finally { - next(); - } - } -} diff --git a/src/common/sentry.ts b/src/common/sentry.ts deleted file mode 100644 index 8c386c4499..0000000000 --- a/src/common/sentry.ts +++ /dev/null @@ -1,78 +0,0 @@ -/** - * 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 { Dedupe, Offline } from "@sentry/integrations"; -import * as Sentry from "@sentry/electron"; -import { sentryDsn, isProduction } from "./vars"; -import { UserStore } from "./user-store"; -import { inspect } from "util"; - -/** - * "Translate" 'browser' to 'main' as Lens developer more familiar with the term 'main' - */ -function mapProcessName(processType: string) { - if (processType === "browser") { - return "main"; - } - - return processType; -} - -/** - * Initialize Sentry for the current process so to send errors for debugging. - */ -export function SentryInit() { - const processName = mapProcessName(process.type); - - Sentry.init({ - beforeSend: (event) => { - // default to false, in case instance of UserStore is not created (yet) - const allowErrorReporting = UserStore.getInstance(false)?.allowErrorReporting ?? false; - - if (allowErrorReporting) { - return event; - } - - /** - * Directly write to stdout so that no other integrations capture this and create an infinite loop - */ - process.stdout.write(`🔒 [SENTRY-BEFORE-SEND-HOOK]: allowErrorReporting: ${allowErrorReporting}. Sentry event is caught but not sent to server.`); - process.stdout.write("🔒 [SENTRY-BEFORE-SEND-HOOK]: === START OF SENTRY EVENT ==="); - process.stdout.write(inspect(event, false, null, true)); - process.stdout.write("🔒 [SENTRY-BEFORE-SEND-HOOK]: === END OF SENTRY EVENT ==="); - - // if return null, the event won't be sent - // ref https://github.com/getsentry/sentry-javascript/issues/2039 - return null; - }, - dsn: sentryDsn, - integrations: [ - new Dedupe(), - new Offline(), - ], - initialScope: { - tags: { - "process": processName, - } - }, - environment: isProduction ? "production" : "development", - }); -} diff --git a/src/common/vars.ts b/src/common/vars.ts index 6462be4db5..8b86bd19ad 100644 --- a/src/common/vars.ts +++ b/src/common/vars.ts @@ -74,5 +74,3 @@ export const supportUrl = "https://docs.k8slens.dev/latest/support/" as string; export const appSemVer = new SemVer(packageInfo.version); export const docsUrl = "https://docs.k8slens.dev/main/" as string; - -export const sentryDsn = packageInfo.config?.sentryDsn ?? ""; diff --git a/src/main/index.ts b/src/main/index.ts index 3dd478fc76..72947e16e7 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -58,7 +58,6 @@ import { UserStore } from "../common/user-store"; import { WeblinkStore } from "../common/weblink-store"; import { ExtensionsStore } from "../extensions/extensions-store"; import { FilesystemProvisionerStore } from "./extension-filesystem"; -import { SentryInit } from "../common/sentry"; import { ensureDir } from "fs-extra"; import { Router } from "./router"; import { initMenu } from "./menu"; @@ -71,7 +70,6 @@ const onQuitCleanup = disposer(); const workingDir = path.join(app.getPath("appData"), appName); -SentryInit(); app.setName(appName); logger.info(`📟 Setting ${productName} as protocol client for lens://`); diff --git a/src/renderer/bootstrap.tsx b/src/renderer/bootstrap.tsx index b6b97cfc6b..a99737a303 100644 --- a/src/renderer/bootstrap.tsx +++ b/src/renderer/bootstrap.tsx @@ -48,7 +48,6 @@ import { WeblinkStore } from "../common/weblink-store"; import { ExtensionsStore } from "../extensions/extensions-store"; import { FilesystemProvisionerStore } from "../main/extension-filesystem"; import { ThemeStore } from "./theme.store"; -import { SentryInit } from "../common/sentry"; import { TerminalStore } from "./components/dock/terminal.store"; import cloudsMidnight from "./monaco-themes/Clouds Midnight.json"; @@ -92,8 +91,6 @@ export async function bootstrap(App: AppComponent) { UserStore.createInstance(); - SentryInit(); - // ClusterStore depends on: UserStore const cs = ClusterStore.createInstance(); diff --git a/src/renderer/components/+preferences/preferences.tsx b/src/renderer/components/+preferences/preferences.tsx index 2abed711e6..765e9ddf64 100644 --- a/src/renderer/components/+preferences/preferences.tsx +++ b/src/renderer/components/+preferences/preferences.tsx @@ -51,7 +51,6 @@ import { Editor } from "./editor"; import { LensProxy } from "./proxy"; import { Telemetry } from "./telemetry"; import { Extensions } from "./extensions"; -import { sentryDsn } from "../../../common/vars"; @observer export class Preferences extends React.Component { @@ -75,7 +74,7 @@ export class Preferences extends React.Component { - {(telemetryExtensions.length > 0 || !!sentryDsn) && + {telemetryExtensions.length > 0 && } {extensions.filter(e => !e.showInPreferencesTab).length > 0 && diff --git a/src/renderer/components/+preferences/telemetry.tsx b/src/renderer/components/+preferences/telemetry.tsx index 5414382f92..1708278ea9 100644 --- a/src/renderer/components/+preferences/telemetry.tsx +++ b/src/renderer/components/+preferences/telemetry.tsx @@ -20,11 +20,7 @@ */ import { observer } from "mobx-react"; import React from "react"; -import { UserStore } from "../../../common/user-store"; -import { sentryDsn } from "../../../common/vars"; import { AppPreferenceRegistry } from "../../../extensions/registries"; -import { Checkbox } from "../checkbox"; -import { SubTitle } from "../layout/sub-title"; import { ExtensionSettings } from "./preferences"; export const Telemetry = observer(() => { @@ -35,29 +31,6 @@ export const Telemetry = observer(() => {

Telemetry

{telemetryExtensions.map((extension) => )} - {sentryDsn ? ( - -
- - { - UserStore.getInstance().allowErrorReporting = value; - }} - /> -
- - Automatic error reports provide vital information about issues and application crashes. - It is highly recommended to keep this feature enabled to ensure fast turnaround for issues you might encounter. - -
-
-
-
) : - // we don't need to shows the checkbox at all if Sentry dsn is not a valid url - null - }
); }); diff --git a/src/renderer/components/error-boundary/error-boundary.tsx b/src/renderer/components/error-boundary/error-boundary.tsx index dd345e9f48..0230b65160 100644 --- a/src/renderer/components/error-boundary/error-boundary.tsx +++ b/src/renderer/components/error-boundary/error-boundary.tsx @@ -19,56 +19,74 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import "./error-boundary.scss"; - -import React from "react"; -import { Button } from "../button"; -import { navigation } from "../../navigation"; -import { issuesTrackerUrl, slackUrl } from "../../../common/vars"; -import * as Sentry from "@sentry/react"; -import { observer } from "mobx-react"; - -@observer -export class ErrorBoundary extends React.Component { - render() { - return ( - { - const slackLink = Slack; - const githubLink = GitHub; - const pageUrl = location.pathname; - - return ( -
-
- App crash at {pageUrl} -
-

- To help us improve the product please report bugs to {slackLink} community or {githubLink} issues tracker. -

-
- -

Component stack:

- {componentStack} -
- -

Error stack:


- {error.stack} -
-
-
- ); - }}> - {this.props.children} -
- ); - } -} + import React, { ErrorInfo } from "react"; + import { reaction } from "mobx"; + import { disposeOnUnmount, observer } from "mobx-react"; + import { Button } from "../button"; + import { navigation } from "../../navigation"; + import { issuesTrackerUrl, slackUrl } from "../../../common/vars"; + + interface Props { + } + + interface State { + error?: Error; + errorInfo?: ErrorInfo; + } + + @observer + export class ErrorBoundary extends React.Component { + public state: State = {}; + + @disposeOnUnmount + resetOnNavigate = reaction( + () => navigation.toString(), + () => this.setState({ error: null, errorInfo: null }) + ); + + componentDidCatch(error: Error, errorInfo: ErrorInfo) { + this.setState({ error, errorInfo }); + } + + back = () => { + navigation.goBack(); + }; + + render() { + const { error, errorInfo } = this.state; + + if (error) { + const slackLink = Slack; + const githubLink = Github; + const pageUrl = location.pathname; + + return ( +
+
+ App crash at {pageUrl} +
+

+ To help us improve the product please report bugs to {slackLink} community or {githubLink} issues tracker. +

+
+ +

Component stack:

+ {errorInfo.componentStack} +
+ +

Error stack:


+ {error.stack} +
+
+
+ ); + } + + return this.props.children; + } + } \ No newline at end of file