Automatic error reporting (#7046)
* Enable sentry global handlers if automaticErrorReporting is on * Pass the exception through on session restore error Passing the exception object itself through to the BugReportDialog means a stack trace can be correctly recorded in Sentry
This commit is contained in:
parent
d0bb6e0657
commit
3defb863b3
6 changed files with 37 additions and 12 deletions
|
@ -59,6 +59,7 @@ import SessionRestoreErrorDialog from "./components/views/dialogs/SessionRestore
|
||||||
import StorageEvictedDialog from "./components/views/dialogs/StorageEvictedDialog";
|
import StorageEvictedDialog from "./components/views/dialogs/StorageEvictedDialog";
|
||||||
|
|
||||||
import { logger } from "matrix-js-sdk/src/logger";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
|
import { setSentryUser } from "./sentry";
|
||||||
|
|
||||||
const HOMESERVER_URL_KEY = "mx_hs_url";
|
const HOMESERVER_URL_KEY = "mx_hs_url";
|
||||||
const ID_SERVER_URL_KEY = "mx_is_url";
|
const ID_SERVER_URL_KEY = "mx_is_url";
|
||||||
|
@ -455,7 +456,7 @@ async function handleLoadSessionFailure(e: Error): Promise<boolean> {
|
||||||
logger.error("Unable to load session", e);
|
logger.error("Unable to load session", e);
|
||||||
|
|
||||||
const modal = Modal.createTrackedDialog('Session Restore Error', '', SessionRestoreErrorDialog, {
|
const modal = Modal.createTrackedDialog('Session Restore Error', '', SessionRestoreErrorDialog, {
|
||||||
error: e.message,
|
error: e,
|
||||||
});
|
});
|
||||||
|
|
||||||
const [success] = await modal.finished;
|
const [success] = await modal.finished;
|
||||||
|
@ -582,6 +583,8 @@ async function doSetLoggedIn(
|
||||||
|
|
||||||
PosthogAnalytics.instance.updateAnonymityFromSettings(credentials.userId);
|
PosthogAnalytics.instance.updateAnonymityFromSettings(credentials.userId);
|
||||||
|
|
||||||
|
setSentryUser(credentials.userId);
|
||||||
|
|
||||||
const client = MatrixClientPeg.get();
|
const client = MatrixClientPeg.get();
|
||||||
|
|
||||||
if (credentials.freshLogin && SettingsStore.getValue("feature_dehydration")) {
|
if (credentials.freshLogin && SettingsStore.getValue("feature_dehydration")) {
|
||||||
|
|
|
@ -28,13 +28,15 @@ import DialogButtons from "../elements/DialogButtons";
|
||||||
import { IDialogProps } from "./IDialogProps";
|
import { IDialogProps } from "./IDialogProps";
|
||||||
|
|
||||||
interface IProps extends IDialogProps {
|
interface IProps extends IDialogProps {
|
||||||
error: string;
|
error: Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@replaceableComponent("views.dialogs.SessionRestoreErrorDialog")
|
@replaceableComponent("views.dialogs.SessionRestoreErrorDialog")
|
||||||
export default class SessionRestoreErrorDialog extends React.Component<IProps> {
|
export default class SessionRestoreErrorDialog extends React.Component<IProps> {
|
||||||
private sendBugReport = (): void => {
|
private sendBugReport = (): void => {
|
||||||
Modal.createTrackedDialog('Session Restore Error', 'Send Bug Report Dialog', BugReportDialog, {});
|
Modal.createTrackedDialog('Session Restore Error', 'Send Bug Report Dialog', BugReportDialog, {
|
||||||
|
error: this.props.error,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
private onClearStorageClick = (): void => {
|
private onClearStorageClick = (): void => {
|
||||||
|
|
|
@ -92,6 +92,7 @@ export default class LabsUserSettingsTab extends React.Component<{}, IState> {
|
||||||
<SettingsFlag name="enableWidgetScreenshots" level={SettingLevel.ACCOUNT} />
|
<SettingsFlag name="enableWidgetScreenshots" level={SettingLevel.ACCOUNT} />
|
||||||
<SettingsFlag name="showHiddenEventsInTimeline" level={SettingLevel.DEVICE} />
|
<SettingsFlag name="showHiddenEventsInTimeline" level={SettingLevel.DEVICE} />
|
||||||
<SettingsFlag name="lowBandwidth" level={SettingLevel.DEVICE} />
|
<SettingsFlag name="lowBandwidth" level={SettingLevel.DEVICE} />
|
||||||
|
<SettingsFlag name="automaticErrorReporting" level={SettingLevel.DEVICE} />
|
||||||
{ hiddenReadReceipts }
|
{ hiddenReadReceipts }
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -890,6 +890,7 @@
|
||||||
"Display Communities instead of Spaces": "Display Communities instead of Spaces",
|
"Display Communities instead of Spaces": "Display Communities instead of Spaces",
|
||||||
"Temporarily show communities instead of Spaces for this session. Support for this will be removed in the near future. This will reload Element.": "Temporarily show communities instead of Spaces for this session. Support for this will be removed in the near future. This will reload Element.",
|
"Temporarily show communities instead of Spaces for this session. Support for this will be removed in the near future. This will reload Element.": "Temporarily show communities instead of Spaces for this session. Support for this will be removed in the near future. This will reload Element.",
|
||||||
"Developer mode": "Developer mode",
|
"Developer mode": "Developer mode",
|
||||||
|
"Automatically send debug logs on any error": "Automatically send debug logs on any error",
|
||||||
"Collecting app version information": "Collecting app version information",
|
"Collecting app version information": "Collecting app version information",
|
||||||
"Collecting logs": "Collecting logs",
|
"Collecting logs": "Collecting logs",
|
||||||
"Uploading logs": "Uploading logs",
|
"Uploading logs": "Uploading logs",
|
||||||
|
|
|
@ -192,6 +192,11 @@ export async function sendSentryReport(userText: string, issueUrl: string, error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setSentryUser(mxid: string): void {
|
||||||
|
if (!SdkConfig.get().sentry || !SettingsStore.getValue("automaticErrorReporting")) return;
|
||||||
|
Sentry.setUser({ username: mxid });
|
||||||
|
}
|
||||||
|
|
||||||
interface ISentryConfig {
|
interface ISentryConfig {
|
||||||
dsn: string;
|
dsn: string;
|
||||||
environment?: string;
|
environment?: string;
|
||||||
|
@ -199,21 +204,28 @@ interface ISentryConfig {
|
||||||
|
|
||||||
export async function initSentry(sentryConfig: ISentryConfig): Promise<void> {
|
export async function initSentry(sentryConfig: ISentryConfig): Promise<void> {
|
||||||
if (!sentryConfig) return;
|
if (!sentryConfig) return;
|
||||||
|
// Only enable Integrations.GlobalHandlers, which hooks uncaught exceptions, if automaticErrorReporting is true
|
||||||
|
const integrations = [
|
||||||
|
new Sentry.Integrations.InboundFilters(),
|
||||||
|
new Sentry.Integrations.FunctionToString(),
|
||||||
|
new Sentry.Integrations.Breadcrumbs(),
|
||||||
|
new Sentry.Integrations.UserAgent(),
|
||||||
|
new Sentry.Integrations.Dedupe(),
|
||||||
|
];
|
||||||
|
|
||||||
|
if (SettingsStore.getValue("automaticErrorReporting")) {
|
||||||
|
integrations.push(new Sentry.Integrations.GlobalHandlers(
|
||||||
|
{ onerror: false, onunhandledrejection: true }));
|
||||||
|
integrations.push(new Sentry.Integrations.TryCatch());
|
||||||
|
}
|
||||||
|
|
||||||
Sentry.init({
|
Sentry.init({
|
||||||
dsn: sentryConfig.dsn,
|
dsn: sentryConfig.dsn,
|
||||||
release: process.env.VERSION,
|
release: process.env.VERSION,
|
||||||
environment: sentryConfig.environment,
|
environment: sentryConfig.environment,
|
||||||
defaultIntegrations: false,
|
defaultIntegrations: false,
|
||||||
autoSessionTracking: false,
|
autoSessionTracking: false,
|
||||||
integrations: [
|
integrations,
|
||||||
// specifically disable Integrations.GlobalHandlers, which hooks uncaught exceptions - we don't
|
|
||||||
// want to capture those at this stage, just explicit rageshakes
|
|
||||||
new Sentry.Integrations.InboundFilters(),
|
|
||||||
new Sentry.Integrations.FunctionToString(),
|
|
||||||
new Sentry.Integrations.Breadcrumbs(),
|
|
||||||
new Sentry.Integrations.UserAgent(),
|
|
||||||
new Sentry.Integrations.Dedupe(),
|
|
||||||
],
|
|
||||||
// Set to 1.0 which is reasonable if we're only submitting Rageshakes; will need to be set < 1.0
|
// Set to 1.0 which is reasonable if we're only submitting Rageshakes; will need to be set < 1.0
|
||||||
// if we collect more frequently.
|
// if we collect more frequently.
|
||||||
tracesSampleRate: 1.0,
|
tracesSampleRate: 1.0,
|
||||||
|
|
|
@ -762,6 +762,12 @@ export const SETTINGS: {[setting: string]: ISetting} = {
|
||||||
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
|
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
"automaticErrorReporting": {
|
||||||
|
displayName: _td("Automatically send debug logs on any error"),
|
||||||
|
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
|
||||||
|
default: false,
|
||||||
|
controller: new ReloadOnChangeController(),
|
||||||
|
},
|
||||||
[UIFeature.RoomHistorySettings]: {
|
[UIFeature.RoomHistorySettings]: {
|
||||||
supportedLevels: LEVELS_UI_FEATURE,
|
supportedLevels: LEVELS_UI_FEATURE,
|
||||||
default: true,
|
default: true,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue