({ event })
| 273 | |
| 274 | // ── 5. Errors ───────────────────────────────────────────────────── |
| 275 | async onRunErrorEvent({ event }) { |
| 276 | // Don't post a notice if we're the ones aborting; the `_(interrupted)_` |
| 277 | // marker on the partial reply is the user-visible signal in that case. |
| 278 | if (aborted) return; |
| 279 | // Drain any in-flight text streams so partial replies are finalized |
| 280 | // rather than left dangling (a _thinking…_ or partial message that |
| 281 | // never resolves). Mirror the flush from onRunFinishedEvent. |
| 282 | const tasks: Promise<void>[] = []; |
| 283 | for (const [id, stream] of Array.from(streams.entries())) { |
| 284 | tasks.push( |
| 285 | stream |
| 286 | .finish() |
| 287 | .catch((e) => |
| 288 | console.error("[bot-telegram] stream finalize failed:", e), |
| 289 | ), |
| 290 | ); |
| 291 | streams.delete(id); |
| 292 | finalised.add(id); |
| 293 | } |
| 294 | buffers.clear(); |
| 295 | await Promise.all(tasks); |
| 296 | // Clean up any tool-status placeholders whose END never arrived before |
| 297 | // the error — mark them cancelled rather than leaving "🔧 using <tool>…" |
| 298 | // orphaned in the chat. |
| 299 | await drainToolStatuses((tool) => `⚠️ ${tool} (cancelled)`); |
| 300 | try { |
| 301 | await args.postPlaceholder( |
| 302 | telegramHtml(`⚠️ Agent error: ${event.message ?? "unknown error"}`), |
| 303 | ); |
| 304 | } catch (err) { |
| 305 | console.error("[telegram-renderer] error notice failed:", err); |
| 306 | } |
| 307 | }, |
| 308 | }; |
| 309 | |
| 310 | return { |
nothing calls this directly
no test coverage detected
searching dependent graphs…