Skip to content

[Bug] stop_event() 状态被 clear_result() 重置,导致有回复的过滤插件无法阻断后续 handler #7921

@lingyun14beta

Description

@lingyun14beta

What happened / 发生了什么

此问题是 #7898 的延伸。#7898 修复了 star_request.py 循环缺少 is_stopped()
检查的问题,但在插件有 yield(发送回复)的场景下,修复仍然失效。

原因:respond/stage.py 发送完消息后会调用 event.clear_result() 将 _result
置为 None,而 is_stopped() 完全依赖 _result,clear_result() 之后
is_stopped() 返回 False,star_request.py 循环顶部的检查失效,后续所有
handler 继续执行。

没有 yield 的插件(如 blacklist)不受影响,因为不触发 respond/stage.py,
_result 不会被清除,导致该 bug 非常隐蔽。

Reproduce / 如何复现?

  1. 编写 priority=1 的过滤插件:

    @filter.event_message_type(filter.EventMessageType.ALL, priority=1)
    async def block(self, event: AstrMessageEvent):
    if should_block(event):
    yield event.plain_result("你被拦截了")
    event.stop_event()
    return

  2. 开启 DEBUG 日志,触发该插件

  3. 观察日志:respond/stage.py 发送回复后,后续 handler 仍然被调用

AstrBot version, deployment method (e.g., Windows Docker Desktop deployment), provider used, and messaging platform used. / AstrBot 版本、部署方式(如 Windows Docker Desktop 部署)、使用的提供商、使用的消息平台适配器

v4.23.6 / Windows 服务器 / QQ 个人号

OS

Windows

Logs / 报错日志

[method.star_request:46]: plugin -> astrbot_plugin_temp_block - intercept_temp_message
(stop_event() 在此调用,yield 触发消息发送)
[respond.stage:183]: Prepare to send - 请勿通过临时会话联系我
(respond/stage.py 发送后调用 clear_result(),is_stopped() 被重置为 False)
[method.star_request:46]: plugin -> astrbot_plugin_keywords_reply - on_message
[method.star_request:46]: plugin -> builtin_commands - help
(后续所有 handler 继续执行,stop_event() 完全失效)

Are you willing to submit a PR? / 你愿意提交 PR 吗?

  • Yes!

Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:coreThe bug / feature is about astrbot's core, backendbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions