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

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

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

State: closed
Merged: No


Summary

  • Wrap plugin event handler calls in try-catch so unhandled exceptions are logged to the log file instead of corrupting the TUI display
  • Add await to the event handler call so async errors are properly caught
  • Add a log property (PluginLogger) to PluginInput, giving plugins a proper way to log messages to OpenCode's log file instead of using console.error()

Problem

When plugins call console.error() or throw unhandled errors in their event handlers, the output goes directly to stderr which corrupts the TUI display. For example, a Telegram notification plugin that fails an API call would show its error message inline in the chat window:

[telegram-notify] Failed to send message: {"ok":false,"error_code":400,"description":"Bad Request: can't parse entities..."}

Changes

packages/opencode/src/plugin/index.ts

  • Added try-catch around hook["event"]?.() calls in Bus.subscribeAll
  • Added await to ensure async errors are caught
  • Errors are logged via Log.create() to the log file (not stderr)
  • Created a plugin.user service logger passed to plugins via PluginInput

packages/plugin/src/index.ts

  • Added PluginLogger type with debug, info, warn, error methods
  • Added log: PluginLogger to PluginInput with JSDoc explaining its purpose

Backward Compatibility

  • Fully backward compatible: existing plugins that don't use log continue to work unchanged
  • The log property is additive to PluginInput
  • Plugins using console.error() still work but their output still goes to stderr (the try-catch prevents crashes from unhandled exceptions)

Testing

  • All 903 existing tests pass
  • Full turbo typecheck passes across all 12 packages
**Original Pull Request:** https://github.com/anomalyco/opencode/pull/12926 **State:** closed **Merged:** No --- ## Summary - Wrap plugin `event` handler calls in try-catch so unhandled exceptions are logged to the log file instead of corrupting the TUI display - Add `await` to the event handler call so async errors are properly caught - Add a `log` property (`PluginLogger`) to `PluginInput`, giving plugins a proper way to log messages to OpenCode's log file instead of using `console.error()` ## Problem When plugins call `console.error()` or throw unhandled errors in their `event` handlers, the output goes directly to stderr which corrupts the TUI display. For example, a Telegram notification plugin that fails an API call would show its error message inline in the chat window: ``` [telegram-notify] Failed to send message: {"ok":false,"error_code":400,"description":"Bad Request: can't parse entities..."} ``` ## Changes ### `packages/opencode/src/plugin/index.ts` - Added try-catch around `hook["event"]?.()` calls in `Bus.subscribeAll` - Added `await` to ensure async errors are caught - Errors are logged via `Log.create()` to the log file (not stderr) - Created a `plugin.user` service logger passed to plugins via `PluginInput` ### `packages/plugin/src/index.ts` - Added `PluginLogger` type with `debug`, `info`, `warn`, `error` methods - Added `log: PluginLogger` to `PluginInput` with JSDoc explaining its purpose ## Backward Compatibility - Fully backward compatible: existing plugins that don't use `log` continue to work unchanged - The `log` property is additive to `PluginInput` - Plugins using `console.error()` still work but their output still goes to stderr (the try-catch prevents crashes from unhandled exceptions) ## Testing - All 903 existing tests pass - Full turbo typecheck passes across all 12 packages
yindo added the pull-request label 2026-02-16 18:19:14 -05:00
yindo closed this issue 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#14439