Skip to content

fix: skip unavailable WebUI startup#8800

Closed
he-yufeng wants to merge 2 commits into
AstrBotDevs:masterfrom
he-yufeng:fix/webui-ready-state
Closed

fix: skip unavailable WebUI startup#8800
he-yufeng wants to merge 2 commits into
AstrBotDevs:masterfrom
he-yufeng:fix/webui-ready-state

Conversation

@he-yufeng

@he-yufeng he-yufeng commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Fixes #8795

Modifications / 改动点

  • Stop the dashboard server from starting when the startup WebUI file check or download fails.

  • Keep the core lifecycle running normally when WebUI is unavailable.

  • Add regressions for propagating the unavailable state and skipping dashboard construction.

  • This is NOT a breaking change. / 这不是一个破坏性变更。

Screenshots or Test Results / 运行截图或测试结果

python -m pytest tests\test_main.py -q -p no:cacheprovider
13 passed

python -m ruff check main.py astrbot\core\initial_loader.py tests\test_main.py
All checks passed!

The broader tests/test_dashboard.py collection is currently blocked on this Windows environment by an existing ModuleNotFoundError: tests.fixtures; the focused startup tests are green.


Checklist / 检查清单

  • 👀 My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
    / 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”
  • 🤓 I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in requirements.txt and pyproject.toml.
    / 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到 requirements.txtpyproject.toml 文件相应位置。
  • 😮 My changes do not introduce malicious code.
    / 我的更改没有引入恶意代码。

Summary by Sourcery

Ensure the application continues core startup while cleanly disabling the WebUI when dashboard startup checks fail.

Bug Fixes:

  • Prevent the dashboard server from starting when the WebUI startup checks fail by propagating an unavailable state through the loader.
  • Ensure the core lifecycle initializes and starts normally even when the WebUI is unavailable.

Tests:

  • Add async tests verifying that a failed dashboard file check disables WebUI startup but still runs the core lifecycle.
  • Add tests confirming that the initial loader skips dashboard construction when WebUI is marked unavailable.

@dosubot dosubot Bot added size:XS This PR changes 0-9 lines, ignoring generated files. area:core The bug / feature is about astrbot's core, backend area:webui The bug / feature is about webui(dashboard) of astrbot. labels Jun 15, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a mechanism to disable the WebUI when it is unavailable (e.g., when webui_dir is not provided or dashboard check fails). It adds a webui_available flag to InitialLoader and skips dashboard initialization if this flag is false. Unit tests are added to verify this behavior. Feedback points out that when webui_available is false, awaiting core_task directly without catching asyncio.CancelledError can prevent proper cleanup of resources via core_lifecycle.stop() during shutdown. It is recommended to wrap the await in a try-except block to ensure cleanup is executed.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +39 to +41
if not self.webui_available:
await core_task
return

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

When webui_available is False, the core_task is awaited directly without being wrapped in a try...except asyncio.CancelledError block. This means if the application is cancelled or shut down during this time, the CancelledError will propagate immediately, and core_lifecycle.stop() will never be called. This prevents proper cleanup of resources, database connections, and plugin termination.

Wrapping the await in a try...except block ensures that stop() is always called upon cancellation.

        if not self.webui_available:
            try:
                await core_task
            except asyncio.CancelledError:
                logger.info("🌈 正在关闭 AstrBot...")
                await core_lifecycle.stop()
            return

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. I pushed 92335ce16 to give the no-WebUI path the same cancellation cleanup as the dashboard path: if core_task is cancelled, core_lifecycle.stop() is awaited before returning.

Focused validation:

python -m py_compile astrbot\core\initial_loader.py main.py tests\test_main.py
python -m pytest tests\test_main.py -q
python -m ruff check astrbot\core\initial_loader.py tests\test_main.py main.py
git diff --check upstream/master..HEAD

tests/test_main.py now includes a cancellation regression for this branch.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread main.py

core_lifecycle = InitialLoader(db, log_broker)
core_lifecycle.webui_dir = webui_dir
core_lifecycle.webui_available = webui_dir is not None

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

你好,我简单看了这行代码,想问一下: webui_dir is not None 真的可以等价于 webui_available=True吗?如果可以,能否简单说明一下:一个非 None 的 webui_dir 如何保证它一定指向可用的WebUI dist?如果不能,那我可以认为,存在一个反例,webui_dir 非 None,但 WebUI 实际不可用? 例如在issue #8784 中,data/dist 可以存在并被返回为 webui_dir,但它可能缺少 index.html 或 assets。这种情况下 webui_dir is not None 为 True,但 WebUI 并不可用。

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right that webui_dir is not None is not a standalone proof that the dist is complete.

The intended split is:

So this line is safe only with that check_dashboard_files() contract. Without #8785, your counterexample is valid. I kept the changes separate because one PR validates the cached dist and this one handles the no-WebUI runtime path.

@dosubot dosubot Bot added size:S This PR changes 10-29 lines, ignoring generated files. and removed size:XS This PR changes 0-9 lines, ignoring generated files. labels Jun 15, 2026
@Soulter Soulter closed this Jun 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:core The bug / feature is about astrbot's core, backend area:webui The bug / feature is about webui(dashboard) of astrbot. size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] WebUI 下载dashboard.zip失败后,日志显示下载失败,WebUI将不可用,但是出现WebUI is ready的提示

3 participants