diff --git a/src/components/views/dialogs/BugReportDialog.tsx b/src/components/views/dialogs/BugReportDialog.tsx index b12aecd95c..08d295d8b7 100644 --- a/src/components/views/dialogs/BugReportDialog.tsx +++ b/src/components/views/dialogs/BugReportDialog.tsx @@ -29,7 +29,7 @@ import BaseDialog from "./BaseDialog"; import Field from '../elements/Field'; import Spinner from "../elements/Spinner"; import DialogButtons from "../elements/DialogButtons"; -import {sendSentryReport} from "../../../sentry"; +import { sendSentryReport } from "../../../sentry"; interface IProps { onFinished: (success: boolean) => void; @@ -116,11 +116,7 @@ export default class BugReportDialog extends React.Component { } }); - // Send a Sentry report if the user agreed to send logs and if there's an error object (Sentry won't be very - // useful for grouping errors without exception information to aggregate with) - if (sendLogs) { - sendSentryReport(userText, this.props.label, this.props.error); - } + sendSentryReport(userText, this.state.issueUrl, this.props.error); }; private onDownload = async (): Promise => { diff --git a/src/components/views/messages/TileErrorBoundary.tsx b/src/components/views/messages/TileErrorBoundary.tsx index c61771f396..a15806ae0c 100644 --- a/src/components/views/messages/TileErrorBoundary.tsx +++ b/src/components/views/messages/TileErrorBoundary.tsx @@ -51,6 +51,7 @@ export default class TileErrorBoundary extends React.Component { private onBugReport = (): void => { Modal.createTrackedDialog('Bug Report Dialog', '', BugReportDialog, { label: 'react-soft-crash-tile', + error: this.state.error, }); }; diff --git a/src/sentry.ts b/src/sentry.ts index 31f56e9db5..841eac2f24 100644 --- a/src/sentry.ts +++ b/src/sentry.ts @@ -98,30 +98,35 @@ function getDeviceContext(client: MatrixClient): Record { return result; } -async function getContext() { +async function getContexts() { const client = MatrixClientPeg.get(); return { - "contexts": { - "user": getUserContext(client), - "crypto": await getCryptoContext(client), - "device": getDeviceContext(client), - "storage": await getStorageOptions(), - }, - "extra": { - - }, + "user": getUserContext(client), + "crypto": await getCryptoContext(client), + "device": getDeviceContext(client), + "storage": await getStorageOptions(), }; } -export async function sendSentryReport(userText: string, label: string, error: Error): void { - if (!SdkConfig.get()["sentry"]) return; +export async function sendSentryReport(userText: string, issueUrl: string, error: Error): void { + const sentryConfig = SdkConfig.get()["sentry"]; + if (!sentryConfig) return; - // Ignore reports without errors, as they're not useful in sentry and can't easily be aggregated + const captureContext = { + "contexts": await getContexts(), + "extra": { + "userText": userText, + "issue_url": issueUrl, + }, + }; + + // If there's no error and no issueUrl, the report will just produce non-grouped noise in Sentry, so don't + // upload it if (error) { - Sentry.captureException(error, await getContext()); + Sentry.captureException(error, captureContext); + } else if (issueUrl) { + Sentry.captureMessage(`Issue: ${issueUrl}`, captureContext); } - - // TODO: use https://docs.sentry.io/api/projects/submit-user-feedback/ to submit userText } interface ISentryConfig {