feat: remove bugsnag (#931)

This commit is contained in:
Mo
2022-03-15 13:53:29 -05:00
committed by GitHub
parent bd6a883679
commit bcfb22fef6
11 changed files with 3 additions and 292 deletions

View File

@@ -2,7 +2,6 @@
declare global {
interface Window {
bugsnagApiKey?: string;
dashboardUrl?: string;
defaultSyncServer: string;
devAccountEmail?: string;
@@ -22,7 +21,6 @@ import { render } from 'preact';
import { ApplicationGroupView } from './components/ApplicationGroupView';
import { Bridge } from './services/bridge';
import { BrowserBridge } from './services/browserBridge';
import { startErrorReporting } from './services/errorReporting';
import { StartApplication } from './startApplication';
import { ApplicationGroup } from './ui_models/application_group';
import { isDev } from './utils';
@@ -34,7 +32,7 @@ const startApplication: StartApplication = async function startApplication(
webSocketUrl: string
) {
SNLog.onLog = console.log;
startErrorReporting();
SNLog.onError = console.error;
const mainApplicationGroup = new ApplicationGroup(
defaultSyncServerHost,

View File

@@ -2,7 +2,7 @@ import { WebApplication } from '@/ui_models/application';
import { AppState } from '@/ui_models/app_state';
import { FunctionComponent } from 'preact';
import { PreferencesPane } from '../components';
import { ErrorReporting, Tools, Defaults, LabsPane } from './general-segments';
import { Tools, Defaults, LabsPane } from './general-segments';
import { ExtensionsLatestVersions } from '@/preferences/panes/extensions-segments';
import { Advanced } from '@/preferences/panes/account';
import { observer } from 'mobx-react-lite';
@@ -18,7 +18,6 @@ export const General: FunctionComponent<GeneralProps> = observer(
<PreferencesPane>
<Tools application={application} />
<Defaults application={application} />
<ErrorReporting appState={appState} />
<LabsPane application={application} />
<Advanced
application={application}

View File

@@ -1,86 +0,0 @@
import { useState } from 'preact/hooks';
import { storage, StorageKey } from '@Services/localStorage';
import { disableErrorReporting, enableErrorReporting, errorReportingId } from '@Services/errorReporting';
import { alertDialog } from '@Services/alertService';
import { observer } from 'mobx-react-lite';
import { AppState } from '@/ui_models/app_state';
import { FunctionComponent } from 'preact';
import { PreferencesGroup, PreferencesSegment, Title, Text } from '@/preferences/components';
import { Switch } from '@/components/Switch';
type Props = {
appState: AppState;
}
export const ErrorReporting: FunctionComponent<Props> = observer(({ appState }: Props) => {
const [isErrorReportingEnabled] = useState(() => storage.get(StorageKey.DisableErrorReporting) === false);
const [errorReportingIdValue] = useState(() => errorReportingId());
const toggleErrorReportingEnabled = () => {
if (isErrorReportingEnabled) {
disableErrorReporting();
} else {
enableErrorReporting();
}
if (!appState.sync.inProgress) {
window.location.reload();
}
};
const openErrorReportingDialog = () => {
alertDialog({
title: 'Data sent during automatic error reporting',
text: `
We use <a target="_blank" rel="noreferrer" href="https://www.bugsnag.com/">Bugsnag</a>
to automatically report errors that occur while the app is running. See
<a target="_blank" rel="noreferrer" href="https://docs.bugsnag.com/platforms/javascript/#sending-diagnostic-data">
this article, paragraph 'Browser' under 'Sending diagnostic data',
</a>
to see what data is included in error reports.
<br><br>
Error reports never include IP addresses and are fully
anonymized. We use error reports to be alerted when something in our
code is causing unexpected errors and crashes in your application
experience.
`
});
};
return (
<PreferencesGroup>
<PreferencesSegment>
<div className="flex flex-row items-center">
<div className="flex-grow flex flex-col">
<Title>Error Reporting</Title>
<Text>
Help us improve Standard Notes by automatically submitting
anonymized error reports.
</Text>
</div>
<div className="flex flex-col justify-center items-center min-w-15">
<Switch onChange={toggleErrorReportingEnabled} checked={isErrorReportingEnabled} />
</div>
</div>
<div className="min-h-2" />
{errorReportingIdValue && (
<>
<Text>
Your random identifier is <span className="font-bold">{errorReportingIdValue}</span>
</Text>
<Text>
Disabling error reporting will remove that identifier from your
local storage, and a new identifier will be created should you
decide to enable error reporting again in the future.
</Text>
</>
)}
<Text>
<a className="cursor-pointer" onClick={openErrorReportingDialog}>What data is being sent?</a>
</Text>
</PreferencesSegment>
</PreferencesGroup>
);
});

View File

@@ -1,4 +1,3 @@
export * from './ErrorReporting';
export * from './Tools';
export * from './Defaults';
export * from './Labs';

View File

@@ -1,115 +0,0 @@
import { isNullOrUndefined, SNLog } from '@standardnotes/snjs';
import { getDesktopVersion, isDesktopApplication, isDev } from '@/utils';
import { storage, StorageKey } from './localStorage';
import Bugsnag from '@bugsnag/js';
import { WebCrypto } from '../crypto';
import { WebAppVersion } from '@/version';
function redactFilePath(line: string): string {
const fileName = line.match(/\w+\.(html|js)/)?.[0];
const redacted = '<redacted file path>';
if (fileName) {
return redacted + '/' + fileName;
} else {
return redacted;
}
}
export function startErrorReporting(): void {
const disableErrorReporting = storage.get(StorageKey.DisableErrorReporting);
if (
/**
* Error reporting used to be opt-out, but is now opt-in, so
* treat the absence of an error reporting preference as an indication
* to disable error reporting.
*/
isNullOrUndefined(disableErrorReporting) ||
disableErrorReporting ||
!window.bugsnagApiKey
) {
SNLog.onError = console.error;
return;
}
try {
const storedUserId = storage.get(StorageKey.AnonymousUserId);
let anonymousUserId: string;
if (storedUserId === null) {
anonymousUserId = WebCrypto.generateUUID();
storage.set(StorageKey.AnonymousUserId, anonymousUserId);
} else {
anonymousUserId = storedUserId;
}
Bugsnag.start({
apiKey: window.bugsnagApiKey,
appType: isDesktopApplication() ? 'desktop' : 'web',
appVersion: getDesktopVersion() || WebAppVersion,
collectUserIp: false,
autoTrackSessions: false,
releaseStage: isDev ? 'development' : undefined,
enabledBreadcrumbTypes: ['error', 'log'],
onError(event) {
event.setUser(anonymousUserId);
/**
* Redact any data that could be used to identify user,
* such as file paths.
*/
if (isDesktopApplication()) {
if (event.context) {
event.context = `Desktop/${redactFilePath(event.context)}`;
}
}
if (event.request.url?.includes('file:')) {
event.request.url = redactFilePath(event.request.url);
}
const originalStack = event.originalError.stack;
if (
typeof originalStack === 'string' &&
originalStack.includes('file:')
) {
event.originalError.stack = originalStack
.split('\n')
.map((line) =>
line.includes('file:') ? redactFilePath(line) : line
)
.join('\n');
}
for (const error of event.errors) {
for (const stackFrame of error.stacktrace) {
if (stackFrame.file.includes('file:')) {
stackFrame.file = redactFilePath(stackFrame.file);
}
}
}
},
});
if (isDev) {
SNLog.onError = console.error;
} else {
SNLog.onError = (error) => {
Bugsnag.notify(error);
};
}
} catch (error) {
console.error('Failed to start Bugsnag.', error);
SNLog.onError = console.error;
}
}
export function disableErrorReporting() {
storage.remove(StorageKey.AnonymousUserId);
storage.set(StorageKey.DisableErrorReporting, true);
}
export function enableErrorReporting() {
storage.set(StorageKey.DisableErrorReporting, false);
}
export function errorReportingId() {
return storage.get(StorageKey.AnonymousUserId);
}

View File

@@ -1,16 +1,14 @@
export enum StorageKey {
DisableErrorReporting = 'DisableErrorReporting',
AnonymousUserId = 'AnonymousUserId',
ShowBetaWarning = 'ShowBetaWarning',
ShowNoAccountWarning = 'ShowNoAccountWarning',
}
export type StorageValue = {
[StorageKey.DisableErrorReporting]: boolean;
[StorageKey.AnonymousUserId]: string;
[StorageKey.ShowBetaWarning]: boolean;
[StorageKey.ShowNoAccountWarning]: boolean;
}
};
export const storage = {
get<K extends StorageKey>(key: K): StorageValue[K] | null {