fix: time out stalled feedback submissions (#3778)

This commit is contained in:
Neil
2026-05-30 09:54:23 -07:00
committed by GitHub
parent be8e8cd22d
commit e5fcb2e2d1
2 changed files with 44 additions and 6 deletions
+29 -1
View File
@@ -1,4 +1,4 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
const { fetchMock, handlers } = vi.hoisted(() => ({
fetchMock: vi.fn(),
@@ -29,11 +29,16 @@ function postedBody(): Record<string, unknown> {
describe('submitFeedback', () => {
beforeEach(() => {
vi.useRealTimers()
handlers.clear()
fetchMock.mockReset()
fetchMock.mockResolvedValue(okResponse())
})
afterEach(() => {
vi.useRealTimers()
})
it('strips GitHub identity and anonymous contact fields when submitted anonymously', async () => {
const anonymousArgs = {
feedback: 'private bug report',
@@ -94,6 +99,29 @@ describe('submitFeedback', () => {
})
})
it('falls back when the primary feedback request stalls', async () => {
vi.useFakeTimers()
fetchMock.mockImplementation((url: string, init?: RequestInit) => {
if (url.includes('api.onorca.dev')) {
return new Promise((_resolve, reject) => {
init?.signal?.addEventListener('abort', () => reject(new Error('request aborted')))
})
}
return Promise.resolve(okResponse())
})
const result = submitFeedback({
feedback: 'stalled primary',
submitAnonymously: false,
githubLogin: 'trusted-user',
githubEmail: 'trusted@example.com'
})
await vi.advanceTimersByTimeAsync(10_000)
await expect(Promise.race([result, Promise.resolve('pending')])).resolves.toEqual({ ok: true })
expect(fetchMock).toHaveBeenCalledTimes(2)
})
it('forces renderer IPC submissions onto the feedback lane', async () => {
registerFeedbackHandlers()
await handlers.get('feedback:submit')?.(null, {
+15 -5
View File
@@ -8,6 +8,7 @@ import { app, ipcMain, net } from 'electron'
// same pattern used by updater-changelog.ts and updater-nudge.ts.
const FEEDBACK_API_URL = 'https://api.onorca.dev/v1/feedback'
const FEEDBACK_API_FALLBACK_URL = 'https://www.onorca.dev/v1/feedback'
const FEEDBACK_REQUEST_TIMEOUT_MS = 10_000
export type FeedbackSubmissionType = 'feedback' | 'crash'
@@ -61,11 +62,20 @@ function buildSubmitBody(args: InternalFeedbackSubmitArgs): FeedbackSubmitBody {
}
async function postFeedback(url: string, body: FeedbackSubmitBody): Promise<Response> {
return net.fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body)
})
const controller = new AbortController()
// Why: a silent feedback endpoint should not leave IPC or crash-report
// submission flows pending forever.
const timeout = setTimeout(() => controller.abort(), FEEDBACK_REQUEST_TIMEOUT_MS)
try {
return await net.fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
signal: controller.signal
})
} finally {
clearTimeout(timeout)
}
}
export async function submitFeedback(