refactor(features): fix empty catches and remove AI slop from manager modules
This commit is contained in:
@@ -191,6 +191,19 @@ export class BackgroundManager {
|
||||
this.registerProcessCleanup()
|
||||
}
|
||||
|
||||
private async abortSessionWithLogging(sessionID: string, reason: string): Promise<void> {
|
||||
try {
|
||||
await this.client.session.abort({
|
||||
path: { id: sessionID },
|
||||
})
|
||||
} catch (error) {
|
||||
log(`[background-agent] Failed to abort session during ${reason}:`, {
|
||||
sessionID,
|
||||
error,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async assertCanSpawn(parentSessionID: string): Promise<SubagentSpawnContext> {
|
||||
const spawnContext = await resolveSubagentSpawnContext(this.client, parentSessionID)
|
||||
const maxDepth = getMaxSubagentDepth(this.config)
|
||||
@@ -448,11 +461,7 @@ export class BackgroundManager {
|
||||
const sessionID = createResult.data.id
|
||||
|
||||
if (task.status === "cancelled") {
|
||||
await this.client.session.abort({
|
||||
path: { id: sessionID },
|
||||
}).catch((error) => {
|
||||
log("[background-agent] Failed to abort cancelled pre-start session:", error)
|
||||
})
|
||||
await this.abortSessionWithLogging(sessionID, "cancelled pre-start cleanup")
|
||||
this.concurrencyManager.release(concurrencyKey)
|
||||
return
|
||||
}
|
||||
@@ -570,9 +579,7 @@ export class BackgroundManager {
|
||||
|
||||
// Abort the session to prevent infinite polling hang
|
||||
// Awaited to prevent dangling promise during subagent teardown (Bun/WebKit SIGABRT)
|
||||
await this.client.session.abort({
|
||||
path: { id: sessionID },
|
||||
}).catch(() => {})
|
||||
await this.abortSessionWithLogging(sessionID, "launch error cleanup")
|
||||
|
||||
this.markForNotification(existingTask)
|
||||
this.enqueueNotificationForParent(existingTask.parentSessionID, () => this.notifyParentSession(existingTask)).catch(err => {
|
||||
@@ -853,9 +860,7 @@ export class BackgroundManager {
|
||||
// Abort the session to prevent infinite polling hang
|
||||
// Awaited to prevent dangling promise during subagent teardown (Bun/WebKit SIGABRT)
|
||||
if (existingTask.sessionID) {
|
||||
await this.client.session.abort({
|
||||
path: { id: existingTask.sessionID },
|
||||
}).catch(() => {})
|
||||
await this.abortSessionWithLogging(existingTask.sessionID, "resume error cleanup")
|
||||
}
|
||||
|
||||
this.markForNotification(existingTask)
|
||||
@@ -879,7 +884,11 @@ export class BackgroundManager {
|
||||
(t) => t.status !== "completed" && t.status !== "cancelled"
|
||||
)
|
||||
return incomplete.length > 0
|
||||
} catch {
|
||||
} catch (error) {
|
||||
log("[background-agent] Failed to check session todos:", {
|
||||
sessionID,
|
||||
error,
|
||||
})
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -1269,7 +1278,6 @@ export class BackgroundManager {
|
||||
return false
|
||||
}
|
||||
|
||||
// Additionally check that at least one message has content (not just empty)
|
||||
// OpenCode API uses different part types than Anthropic's API:
|
||||
// - "reasoning" with .text property (thinking/reasoning content)
|
||||
// - "tool" with .state.output property (tool call results)
|
||||
@@ -1438,9 +1446,7 @@ export class BackgroundManager {
|
||||
|
||||
if (abortSession && task.sessionID) {
|
||||
// Awaited to prevent dangling promise during subagent teardown (Bun/WebKit SIGABRT)
|
||||
await this.client.session.abort({
|
||||
path: { id: task.sessionID },
|
||||
}).catch(() => {})
|
||||
await this.abortSessionWithLogging(task.sessionID, `task cancellation (${source})`)
|
||||
|
||||
SessionCategoryRegistry.remove(task.sessionID)
|
||||
}
|
||||
@@ -1557,9 +1563,7 @@ export class BackgroundManager {
|
||||
|
||||
if (task.sessionID) {
|
||||
// Awaited to prevent dangling promise during subagent teardown (Bun/WebKit SIGABRT)
|
||||
await this.client.session.abort({
|
||||
path: { id: task.sessionID },
|
||||
}).catch(() => {})
|
||||
await this.abortSessionWithLogging(task.sessionID, `task completion (${source})`)
|
||||
|
||||
SessionCategoryRegistry.remove(task.sessionID)
|
||||
}
|
||||
@@ -1576,9 +1580,6 @@ export class BackgroundManager {
|
||||
}
|
||||
|
||||
private async notifyParentSession(task: BackgroundTask): Promise<void> {
|
||||
// Note: Callers must release concurrency before calling this method
|
||||
// to ensure slots are freed even if notification fails
|
||||
|
||||
const duration = formatDuration(task.startedAt ?? new Date(), task.completedAt)
|
||||
|
||||
log("[background-agent] notifyParentSession called for task:", task.id)
|
||||
@@ -1903,16 +1904,11 @@ export class BackgroundManager {
|
||||
continue
|
||||
}
|
||||
|
||||
// Explicit terminal non-idle status (e.g., "interrupted") — complete immediately,
|
||||
// skipping output validation (session will never produce more output).
|
||||
// Unknown statuses fall through to the idle/gone path with output validation.
|
||||
if (sessionStatus && isTerminalSessionStatus(sessionStatus.type)) {
|
||||
await this.tryCompleteTask(task, `polling (terminal session status: ${sessionStatus.type})`)
|
||||
continue
|
||||
}
|
||||
|
||||
// Unknown non-idle status — not active, not terminal, not idle.
|
||||
// Fall through to idle/gone completion path with output validation.
|
||||
if (sessionStatus && sessionStatus.type !== "idle") {
|
||||
log("[background-agent] Unknown session status, treating as potentially idle:", {
|
||||
taskId: task.id,
|
||||
@@ -2065,17 +2061,24 @@ export class BackgroundManager {
|
||||
}
|
||||
|
||||
const previous = this.notificationQueueByParent.get(parentSessionID) ?? Promise.resolve()
|
||||
const cleanupQueueEntry = (): void => {
|
||||
if (this.notificationQueueByParent.get(parentSessionID) === current) {
|
||||
this.notificationQueueByParent.delete(parentSessionID)
|
||||
}
|
||||
}
|
||||
|
||||
const current = previous
|
||||
.catch(() => {})
|
||||
.catch((error) => {
|
||||
log("[background-agent] Continuing notification queue after previous failure:", {
|
||||
parentSessionID,
|
||||
error,
|
||||
})
|
||||
})
|
||||
.then(operation)
|
||||
|
||||
this.notificationQueueByParent.set(parentSessionID, current)
|
||||
|
||||
void current.finally(() => {
|
||||
if (this.notificationQueueByParent.get(parentSessionID) === current) {
|
||||
this.notificationQueueByParent.delete(parentSessionID)
|
||||
}
|
||||
}).catch(() => {})
|
||||
void current.then(cleanupQueueEntry, cleanupQueueEntry)
|
||||
|
||||
return current
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user