[PR #12929] fix: catch plugin event handler errors and provide logger to plugins #14441

Open
opened 2026-02-16 18:19:14 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/anomalyco/opencode/pull/12929

State: open
Merged: No


Fixes #12931

Summary

  • Wrap plugin event handler calls in try-catch with await so that both sync throws and async rejections are caught instead of crashing the TUI or going uncaught.
  • Provide a log property on PluginInput so plugins can log to OpenCode's log file instead of writing to stderr (which corrupts the TUI display).

Problem

Plugin event handlers registered via Bus.subscribeAll were called without error handling:

  1. A sync throw in a handler would propagate up and crash the bus subscriber.
  2. An async rejection (returned rejected promise) was completely uncaught since the handler wasn't awaited.
  3. Plugins had no way to log errors except console.error(), which writes to stderr and corrupts the TUI output.

This was observed in practice when a Telegram notification plugin's API call failed — the error message was rendered directly into the TUI chat window.

Changes

packages/opencode/src/plugin/index.ts

  • Create a scoped logger via Log.create({ service: "plugin.user" })
  • Pass log (with info, warn, error, debug methods) to plugins via PluginInput
  • Wrap each hook["event"]?.() call in try-catch with await, logging errors via the logger

packages/plugin/src/index.ts

  • Add PluginLogger type with info, warn, error, debug methods
  • Add log: PluginLogger to the PluginInput interface

packages/opencode/test/plugin/event-error-handling.test.ts

  • 5 integration tests verifying:
    1. Sync throw doesn't crash the bus
    2. Async rejection doesn't crash the bus
    3. Throwing plugin doesn't prevent other plugins from receiving events
    4. Errors are logged via Log system, not stderr
    5. log property is provided with all expected methods

All 908 tests pass. Typecheck passes across all 12 packages.

**Original Pull Request:** https://github.com/anomalyco/opencode/pull/12929 **State:** open **Merged:** No --- Fixes #12931 ## Summary - **Wrap plugin event handler calls in try-catch with `await`** so that both sync throws and async rejections are caught instead of crashing the TUI or going uncaught. - **Provide a `log` property on `PluginInput`** so plugins can log to OpenCode's log file instead of writing to stderr (which corrupts the TUI display). ## Problem Plugin `event` handlers registered via `Bus.subscribeAll` were called without error handling: 1. A sync `throw` in a handler would propagate up and crash the bus subscriber. 2. An async rejection (returned rejected promise) was completely uncaught since the handler wasn't `await`ed. 3. Plugins had no way to log errors except `console.error()`, which writes to stderr and corrupts the TUI output. This was observed in practice when a Telegram notification plugin's API call failed — the error message was rendered directly into the TUI chat window. ## Changes ### `packages/opencode/src/plugin/index.ts` - Create a scoped logger via `Log.create({ service: "plugin.user" })` - Pass `log` (with `info`, `warn`, `error`, `debug` methods) to plugins via `PluginInput` - Wrap each `hook["event"]?.()` call in try-catch with `await`, logging errors via the logger ### `packages/plugin/src/index.ts` - Add `PluginLogger` type with `info`, `warn`, `error`, `debug` methods - Add `log: PluginLogger` to the `PluginInput` interface ### `packages/opencode/test/plugin/event-error-handling.test.ts` - 5 integration tests verifying: 1. Sync throw doesn't crash the bus 2. Async rejection doesn't crash the bus 3. Throwing plugin doesn't prevent other plugins from receiving events 4. Errors are logged via Log system, not stderr 5. `log` property is provided with all expected methods All 908 tests pass. Typecheck passes across all 12 packages.
yindo added the pull-request label 2026-02-16 18:19:14 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#14441