Route crash reports separately from feedback (#2280)
This commit is contained in:
parent
aff55442d2
commit
c182e09f99
|
|
@ -129,6 +129,7 @@ describe('registerCrashReportingHandlers', () => {
|
|||
expect(submitFeedbackMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
feedback: expect.stringContaining('[Crash Report]'),
|
||||
submissionType: 'crash',
|
||||
githubLogin: 'me',
|
||||
githubEmail: 'me@example.com'
|
||||
})
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ export function registerCrashReportingHandlers(store: CrashReportStore): void {
|
|||
try {
|
||||
const result = await submitFeedback({
|
||||
feedback: formatCrashReportText(report, args.notes),
|
||||
submissionType: 'crash',
|
||||
submitAnonymously: args.submitAnonymously,
|
||||
githubLogin: args.githubLogin,
|
||||
githubEmail: args.githubEmail
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ describe('submitFeedback', () => {
|
|||
const body = postedBody()
|
||||
expect(body).toMatchObject({
|
||||
feedback: 'private bug report',
|
||||
submissionType: 'feedback',
|
||||
githubLogin: null,
|
||||
githubEmail: null,
|
||||
appVersion: '1.2.3-test'
|
||||
|
|
@ -60,9 +61,27 @@ describe('submitFeedback', () => {
|
|||
const body = postedBody()
|
||||
expect(body).toMatchObject({
|
||||
feedback: 'public bug report',
|
||||
submissionType: 'feedback',
|
||||
githubLogin: 'trusted-user',
|
||||
githubEmail: 'trusted@example.com',
|
||||
appVersion: '1.2.3-test'
|
||||
})
|
||||
})
|
||||
|
||||
it('marks crash submissions so the backend can route them separately', async () => {
|
||||
await submitFeedback({
|
||||
feedback: '[Crash Report]',
|
||||
submissionType: 'crash',
|
||||
submitAnonymously: false,
|
||||
githubLogin: 'trusted-user',
|
||||
githubEmail: null
|
||||
})
|
||||
|
||||
expect(postedBody()).toMatchObject({
|
||||
feedback: '[Crash Report]',
|
||||
submissionType: 'crash',
|
||||
githubLogin: 'trusted-user',
|
||||
githubEmail: null
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -9,15 +9,19 @@ import { app, ipcMain, net } from 'electron'
|
|||
const FEEDBACK_API_URL = 'https://api.onorca.dev/v1/feedback'
|
||||
const FEEDBACK_API_FALLBACK_URL = 'https://www.onorca.dev/v1/feedback'
|
||||
|
||||
export type FeedbackSubmissionType = 'feedback' | 'crash'
|
||||
|
||||
export type FeedbackSubmitArgs = {
|
||||
feedback: string
|
||||
submitAnonymously?: boolean
|
||||
githubLogin: string | null
|
||||
githubEmail: string | null
|
||||
submissionType?: FeedbackSubmissionType
|
||||
}
|
||||
|
||||
type FeedbackSubmitBody = {
|
||||
feedback: string
|
||||
submissionType: FeedbackSubmissionType
|
||||
githubLogin: string | null
|
||||
githubEmail: string | null
|
||||
appVersion: string
|
||||
|
|
@ -44,6 +48,7 @@ function buildSubmitBody(args: FeedbackSubmitArgs): FeedbackSubmitBody {
|
|||
// stale renderer state or future identity-shaped fields cannot leak upstream.
|
||||
return {
|
||||
feedback: args.feedback,
|
||||
submissionType: args.submissionType ?? 'feedback',
|
||||
...identity,
|
||||
appVersion: app.getVersion(),
|
||||
platform: process.platform,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import {
|
|||
DialogTitle
|
||||
} from '@/components/ui/dialog'
|
||||
import { formatCrashReportText, type CrashReportRecord } from '../../../../shared/crash-reporting'
|
||||
import type { GitHubViewer } from '../../../../shared/types'
|
||||
|
||||
function formatSummary(report: CrashReportRecord): string {
|
||||
return `${report.processType} ${report.reason}${
|
||||
|
|
@ -25,6 +26,7 @@ export function CrashReportDialog(): React.JSX.Element {
|
|||
const [notes, setNotes] = useState('')
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [submitting, setSubmitting] = useState(false)
|
||||
const [viewer, setViewer] = useState<GitHubViewer | null>(null)
|
||||
const diagnosticText = useMemo(
|
||||
() => (report ? formatCrashReportText(report, notes) : ''),
|
||||
[notes, report]
|
||||
|
|
@ -70,6 +72,32 @@ export function CrashReportDialog(): React.JSX.Element {
|
|||
})
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) {
|
||||
setViewer(null)
|
||||
return
|
||||
}
|
||||
|
||||
let cancelled = false
|
||||
void window.api.gh
|
||||
.viewer()
|
||||
.then((nextViewer) => {
|
||||
if (!cancelled) {
|
||||
setViewer(nextViewer)
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
if (!cancelled) {
|
||||
setViewer(null)
|
||||
console.error('Failed to load GitHub viewer for crash report:', error)
|
||||
}
|
||||
})
|
||||
|
||||
return () => {
|
||||
cancelled = true
|
||||
}
|
||||
}, [open])
|
||||
|
||||
const handleCopy = async (): Promise<void> => {
|
||||
const result = await window.api.crashReports.copyLatestDiagnostics(
|
||||
report ? { reportId: report.id, notes } : {}
|
||||
|
|
@ -102,8 +130,10 @@ export function CrashReportDialog(): React.JSX.Element {
|
|||
const result = await window.api.crashReports.submit({
|
||||
reportId: report.id,
|
||||
notes,
|
||||
submitAnonymously: true,
|
||||
githubLogin: null,
|
||||
// Why: crash reporting must degrade to anonymous if gh is unavailable;
|
||||
// identity lookup is best-effort and never blocks report creation.
|
||||
submitAnonymously: !viewer,
|
||||
githubLogin: viewer?.login ?? null,
|
||||
githubEmail: null
|
||||
})
|
||||
if (!result.ok) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue