-
Notifications
You must be signed in to change notification settings - Fork 119
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1067 from ga-devfront/feat/add-front-sentry-report
[NEW UI] Update page - sentry user feedback
- Loading branch information
Showing
24 changed files
with
472 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,6 +48,7 @@ | |
"vite-plugin-static-copy": "^1.0.6" | ||
}, | ||
"dependencies": { | ||
"@sentry/browser": "^8.41.0", | ||
"axios": "^1.7.7" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
import * as Sentry from '@sentry/browser'; | ||
import { SeverityLevel } from '@sentry/browser'; | ||
import { maskSensitiveInfoInUrl } from '../utils/urlUtils'; | ||
import { Feedback, Logs, LogsFields } from '../types/sentryApi'; | ||
|
||
const adminDir = window.AutoUpgradeVariables.admin_dir; | ||
const feedbackModalTag = 'feedbackModal'; | ||
|
||
Sentry.init({ | ||
dsn: 'https://[email protected]/4507254110552064', | ||
release: `v${window.AutoUpgradeVariables.module_version}`, | ||
sendDefaultPii: false, | ||
beforeSend(event) { | ||
if (event.tags?.source !== feedbackModalTag) { | ||
return null; | ||
} | ||
|
||
if (event.request?.url) { | ||
event.request.url = maskSensitiveInfoInUrl(window.location.href, adminDir); | ||
} | ||
|
||
return event; | ||
}, | ||
beforeBreadcrumb(breadcrumb) { | ||
['url', 'from', 'to'].forEach((key) => { | ||
if (breadcrumb.data?.[key]) { | ||
breadcrumb.data[key] = maskSensitiveInfoInUrl(breadcrumb.data[key], adminDir); | ||
} | ||
}); | ||
|
||
return breadcrumb; | ||
} | ||
}); | ||
|
||
/** | ||
* Sends enriched user feedback to Sentry with optional logs and metadata. | ||
* This function attaches log files, captures a custom event, and optionally sends user feedback with an associated event ID. | ||
* | ||
* @param {string} message - The message to describe the feedback or error. | ||
* @param {Logs} [logs={}] - An object containing optional logs, warnings, and errors to attach. | ||
* @param {Feedback} [feedback={}] - An object containing optional user feedback fields such as email and comments. | ||
* @param {SeverityLevel} [level='error'] - The severity level of the event (e.g., 'info', 'warning', 'error'). | ||
*/ | ||
export function sendUserFeedback( | ||
message: string, | ||
logs: Logs = {}, | ||
feedback: Feedback = {}, | ||
level: SeverityLevel = 'error' | ||
) { | ||
const attachments: { key: LogsFields; filename: string }[] = [ | ||
{ key: LogsFields.LOGS, filename: 'logs.txt' }, | ||
{ key: LogsFields.WARNINGS, filename: 'summary_warnings.txt' }, | ||
{ key: LogsFields.ERRORS, filename: 'summary_errors.txt' } | ||
]; | ||
|
||
attachments.forEach(({ key, filename }) => { | ||
if (logs[key]) { | ||
Sentry.getCurrentScope().addAttachment({ | ||
filename, | ||
data: logs[key], | ||
contentType: 'text/plain' | ||
}); | ||
} | ||
}); | ||
|
||
const maskedUrl = maskSensitiveInfoInUrl(window.location.href, adminDir); | ||
|
||
const eventId = Sentry.captureEvent({ | ||
message, | ||
level, | ||
tags: { | ||
url: maskedUrl, | ||
source: feedbackModalTag | ||
} | ||
}); | ||
|
||
if (feedback.email || feedback.comments) { | ||
Sentry.captureFeedback( | ||
{ | ||
associatedEventId: eventId, | ||
email: feedback.email, | ||
message: feedback.comments ?? '' | ||
}, | ||
{ | ||
captureContext: { | ||
tags: { | ||
url: maskedUrl, | ||
source: feedbackModalTag | ||
} | ||
} | ||
} | ||
); | ||
} | ||
|
||
Sentry.getCurrentScope().clearAttachments(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import DomLifecycle from '../types/DomLifecycle'; | ||
import { sendUserFeedback } from '../api/sentryApi'; | ||
import { Feedback, FeedbackFields, Logs } from '../types/sentryApi'; | ||
|
||
export default class SendErrorReportDialog implements DomLifecycle { | ||
protected readonly formId = 'form-error-feedback'; | ||
|
||
public mount = (): void => { | ||
this.#form.addEventListener('submit', this.#onSubmit); | ||
}; | ||
|
||
public beforeDestroy = (): void => { | ||
this.#form.removeEventListener('submit', this.#onSubmit); | ||
}; | ||
|
||
get #form(): HTMLFormElement { | ||
const form = document.forms.namedItem(this.formId); | ||
if (!form) { | ||
throw new Error('Form not found'); | ||
} | ||
|
||
return form; | ||
} | ||
|
||
#onSubmit = (event: SubmitEvent) => { | ||
event.preventDefault(); | ||
|
||
const logsViewer = document.querySelector('[data-component="logs-viewer"]'); | ||
|
||
const logs: Logs = {}; | ||
|
||
const logsContent = logsViewer?.querySelector('[data-slot-component="list"]'); | ||
if (!logsContent) { | ||
throw new Error('Logs content to send not found'); | ||
} | ||
|
||
const message = logsContent.lastChild?.textContent; | ||
if (!message) { | ||
throw new Error('Message to send not found'); | ||
} | ||
|
||
if (!logsContent.textContent) { | ||
throw new Error('Logs to send not found'); | ||
} | ||
logs.logs = logsContent.textContent; | ||
|
||
const summaryWarningText = logsViewer?.querySelector( | ||
'[data-summary-severity="warning"]' | ||
)?.textContent; | ||
if (summaryWarningText) { | ||
logs.warnings = summaryWarningText; | ||
} | ||
|
||
const summaryErrorText = logsViewer?.querySelector( | ||
'[data-summary-severity="error"]' | ||
)?.textContent; | ||
if (summaryErrorText) { | ||
logs.errors = summaryErrorText; | ||
} | ||
|
||
const feedback: Feedback = {}; | ||
|
||
const form = event.target as HTMLFormElement; | ||
const formData = new FormData(form); | ||
|
||
Object.values(FeedbackFields).forEach((field) => { | ||
const value = formData.get(field); | ||
if (value && typeof value === 'string') { | ||
feedback[field] = value; | ||
} | ||
}); | ||
|
||
sendUserFeedback(message, logs, feedback); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.