Skip to content

Commit a392526

Browse files
committed
fix: make diagnostics instrumentation fail open
1 parent ec54e50 commit a392526

3 files changed

Lines changed: 35 additions & 16 deletions

File tree

packages/app/src/pages/session.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ export default function Page() {
133133
partCount: messages.reduce((count, message) => count + countMessageParts(message), 0),
134134
}
135135
})
136+
const emitDiagnostics = (event: Parameters<typeof emitRendererDiagnostic>[0]) => {
137+
void emitRendererDiagnostic(event).catch(() => undefined)
138+
}
136139

137140
createEffect(
138141
on(
@@ -153,7 +156,7 @@ export default function Page() {
153156
}
154157
},
155158
(state) => {
156-
void emitRendererDiagnostic({
159+
emitDiagnostics({
157160
name: "session.view.state",
158161
route_session_id: state.routeSessionID,
159162
visible_session_id: state.visibleSessionID,
@@ -190,7 +193,7 @@ export default function Page() {
190193
) {
191194
return
192195
}
193-
void emitRendererDiagnostic({
196+
emitDiagnostics({
194197
name: "session.identity.transition",
195198
route_session_id: next.routeSessionID,
196199
visible_session_id: next.visibleSessionID,

packages/app/src/pages/session/use-session-refresh-effects.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,30 @@ export function useSessionRefreshEffects(input: {
2020
let todoTimer: number | undefined
2121

2222
const emitRefresh = (event: RendererDiagnosticInput) => {
23-
void input.emitRendererDiagnostic?.(event)
23+
try {
24+
const pending = input.emitRendererDiagnostic?.(event)
25+
void Promise.resolve(pending).catch(() => undefined)
26+
} catch {}
2427
}
2528

2629
const syncSessionWithDiagnostics = (id: string, options: { force?: boolean } | undefined, cachePresent: boolean) => {
2730
const startedAt = performance.now()
31+
const visibleSessionID = input.timelineSessionID()
2832
const phase = options?.force ? "message_force" : "message"
2933
emitRefresh({
3034
name: "session.data.refresh",
3135
route_session_id: id,
32-
visible_session_id: input.timelineSessionID(),
33-
timeline_session_id: input.timelineSessionID(),
36+
visible_session_id: visibleSessionID,
37+
timeline_session_id: visibleSessionID,
3438
data: { phase: `${phase}_start`, cache_present: cachePresent },
3539
})
3640
void Promise.resolve(input.syncSession(id, options))
3741
.then(() => {
3842
emitRefresh({
3943
name: "session.data.refresh",
4044
route_session_id: id,
41-
visible_session_id: input.timelineSessionID(),
42-
timeline_session_id: input.timelineSessionID(),
45+
visible_session_id: visibleSessionID,
46+
timeline_session_id: visibleSessionID,
4347
data: {
4448
phase: `${phase}_end`,
4549
duration_ms: Math.round(performance.now() - startedAt),
@@ -51,8 +55,8 @@ export function useSessionRefreshEffects(input: {
5155
emitRefresh({
5256
name: "session.data.refresh",
5357
route_session_id: id,
54-
visible_session_id: input.timelineSessionID(),
55-
timeline_session_id: input.timelineSessionID(),
58+
visible_session_id: visibleSessionID,
59+
timeline_session_id: visibleSessionID,
5660
data: {
5761
phase: `${phase}_failed`,
5862
duration_ms: Math.round(performance.now() - startedAt),
@@ -64,10 +68,11 @@ export function useSessionRefreshEffects(input: {
6468

6569
const syncTodoWithDiagnostics = (id: string, options: { force?: boolean } | undefined, cachePresent: boolean) => {
6670
const startedAt = performance.now()
71+
const routeSessionID = input.routeSessionID()
6772
const phase = options?.force ? "todo_force" : "todo"
6873
emitRefresh({
6974
name: "session.data.refresh",
70-
route_session_id: input.routeSessionID(),
75+
route_session_id: routeSessionID,
7176
visible_session_id: id,
7277
timeline_session_id: id,
7378
data: { phase: `${phase}_start`, cache_present: cachePresent },
@@ -76,7 +81,7 @@ export function useSessionRefreshEffects(input: {
7681
.then(() => {
7782
emitRefresh({
7883
name: "session.data.refresh",
79-
route_session_id: input.routeSessionID(),
84+
route_session_id: routeSessionID,
8085
visible_session_id: id,
8186
timeline_session_id: id,
8287
data: {
@@ -89,7 +94,7 @@ export function useSessionRefreshEffects(input: {
8994
.catch(() => {
9095
emitRefresh({
9196
name: "session.data.refresh",
92-
route_session_id: input.routeSessionID(),
97+
route_session_id: routeSessionID,
9398
visible_session_id: id,
9499
timeline_session_id: id,
95100
data: {

packages/desktop-electron/src/main/ipc.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const pickerFilters = (ext?: string[]) => {
3333
const MAX_ATTACHMENT_BYTES = 20 * 1024 * 1024
3434
// Picker approvals are short-lived because they authorize a renderer to request file bytes from main.
3535
const ATTACHMENT_APPROVAL_TTL_MS = 30 * 60 * 1000
36+
const RENDERER_DIAGNOSTICS_TIMEOUT_MS = 5_000
3637
const MAX_APPROVED_ATTACHMENT_PATHS = 1000
3738

3839
function normalizeAttachmentPath(filepath: unknown) {
@@ -359,10 +360,20 @@ export function registerIpcHandlers(deps: Deps) {
359360
let rendererDiagnostics: RendererDiagnosticsSlice
360361
try {
361362
const win = BrowserWindow.fromWebContents(event.sender)
362-
rendererDiagnostics = await deps.rendererDiagnosticsSlice({
363-
sessionID,
364-
windowID: win?.id,
365-
maxBytes: SESSION_EXPORT_RENDERER_DIAGNOSTICS_MAX_BYTES,
363+
let timeout: ReturnType<typeof setTimeout> | undefined
364+
rendererDiagnostics = await Promise.race([
365+
deps.rendererDiagnosticsSlice({
366+
sessionID,
367+
windowID: win?.id,
368+
maxBytes: SESSION_EXPORT_RENDERER_DIAGNOSTICS_MAX_BYTES,
369+
}),
370+
new Promise<RendererDiagnosticsSlice>((_, reject) => {
371+
timeout = setTimeout(() => {
372+
reject(new Error("renderer diagnostics timed out"))
373+
}, RENDERER_DIAGNOSTICS_TIMEOUT_MS)
374+
}),
375+
]).finally(() => {
376+
if (timeout !== undefined) clearTimeout(timeout)
366377
})
367378
} catch {
368379
rendererDiagnostics = emptyRendererDiagnosticsSlice("write_failed", new Date())

0 commit comments

Comments
 (0)