feat(core): add plugin error hook for custom error routing (#5192)

* feat(core): add plugin error hook for custom error routing

* fix(core): align plugin error suppression with event stop state
This commit is contained in:
sanyekana
2026-02-18 21:38:27 +08:00
committed by GitHub
parent 567390e27c
commit c6289d8f75
6 changed files with 46 additions and 4 deletions
+2
View File
@@ -24,6 +24,7 @@ from astrbot.core.star.register import (
register_on_llm_tool_respond as on_llm_tool_respond,
)
from astrbot.core.star.register import register_on_platform_loaded as on_platform_loaded
from astrbot.core.star.register import register_on_plugin_error as on_plugin_error
from astrbot.core.star.register import register_on_using_llm_tool as on_using_llm_tool
from astrbot.core.star.register import (
register_on_waiting_llm_request as on_waiting_llm_request,
@@ -52,6 +53,7 @@ __all__ = [
"on_decorating_result",
"on_llm_request",
"on_llm_response",
"on_plugin_error",
"on_platform_loaded",
"on_waiting_llm_request",
"permission_type",
@@ -8,9 +8,9 @@ from astrbot.core import logger
from astrbot.core.message.message_event_result import MessageEventResult
from astrbot.core.platform.astr_message_event import AstrMessageEvent
from astrbot.core.star.star import star_map
from astrbot.core.star.star_handler import StarHandlerMetadata
from astrbot.core.star.star_handler import EventType, StarHandlerMetadata
from ...context import PipelineContext, call_handler
from ...context import PipelineContext, call_event_hook, call_handler
from ..stage import Stage
@@ -48,10 +48,20 @@ class StarRequestSubStage(Stage):
yield ret
event.clear_result() # 清除上一个 handler 的结果
except Exception as e:
logger.error(traceback.format_exc())
traceback_text = traceback.format_exc()
logger.error(traceback_text)
logger.error(f"Star {handler.handler_full_name} handle error: {e}")
if event.is_at_or_wake_command:
await call_event_hook(
event,
EventType.OnPluginErrorEvent,
md.name,
handler.handler_name,
e,
traceback_text,
)
if not event.is_stopped() and event.is_at_or_wake_command:
ret = f":(\n\n在调用插件 {md.name} 的处理函数 {handler.handler_name} 时出现异常:{e}"
event.set_result(MessageEventResult().message(ret))
yield
+2
View File
@@ -13,6 +13,7 @@ from .star_handler import (
register_on_llm_response,
register_on_llm_tool_respond,
register_on_platform_loaded,
register_on_plugin_error,
register_on_using_llm_tool,
register_on_waiting_llm_request,
register_permission_type,
@@ -32,6 +33,7 @@ __all__ = [
"register_on_decorating_result",
"register_on_llm_request",
"register_on_llm_response",
"register_on_plugin_error",
"register_on_platform_loaded",
"register_on_waiting_llm_request",
"register_permission_type",
@@ -339,6 +339,24 @@ def register_on_platform_loaded(**kwargs):
return decorator
def register_on_plugin_error(**kwargs):
"""当插件处理消息异常时触发。
Hook 参数:
event, plugin_name, handler_name, error, traceback_text
说明:
在 hook 中调用 `event.stop_event()` 可屏蔽默认报错回显,
并由插件自行决定是否转发到其他会话。
"""
def decorator(awaitable):
_ = get_handler_or_create(awaitable, EventType.OnPluginErrorEvent, **kwargs)
return awaitable
return decorator
def register_on_waiting_llm_request(**kwargs):
"""当等待调用 LLM 时的通知事件(在获取锁之前)
+9
View File
@@ -97,6 +97,14 @@ class StarHandlerRegistry(Generic[T]):
plugins_name: list[str] | None = None,
) -> list[StarHandlerMetadata[Callable[..., Awaitable[Any]]]]: ...
@overload
def get_handlers_by_event_type(
self,
event_type: Literal[EventType.OnPluginErrorEvent],
only_activated=True,
plugins_name: list[str] | None = None,
) -> list[StarHandlerMetadata[Callable[..., Awaitable[Any]]]]: ...
@overload
def get_handlers_by_event_type(
self,
@@ -192,6 +200,7 @@ class EventType(enum.Enum):
OnUsingLLMToolEvent = enum.auto() # 使用 LLM 工具
OnLLMToolRespondEvent = enum.auto() # 调用函数工具后
OnAfterMessageSentEvent = enum.auto() # 发送消息后
OnPluginErrorEvent = enum.auto() # 插件处理消息异常时
H = TypeVar("H", bound=Callable[..., Any])
+1
View File
@@ -73,6 +73,7 @@ class PluginRoute(Route):
EventType.OnDecoratingResultEvent: "回复消息前",
EventType.OnCallingFuncToolEvent: "函数工具",
EventType.OnAfterMessageSentEvent: "发送消息后",
EventType.OnPluginErrorEvent: "插件报错时",
}
self._logo_cache = {}