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:
@@ -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
|
||||
|
||||
@@ -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 时的通知事件(在获取锁之前)
|
||||
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -73,6 +73,7 @@ class PluginRoute(Route):
|
||||
EventType.OnDecoratingResultEvent: "回复消息前",
|
||||
EventType.OnCallingFuncToolEvent: "函数工具",
|
||||
EventType.OnAfterMessageSentEvent: "发送消息后",
|
||||
EventType.OnPluginErrorEvent: "插件报错时",
|
||||
}
|
||||
|
||||
self._logo_cache = {}
|
||||
|
||||
Reference in New Issue
Block a user