mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-16 01:40:15 +08:00
102 lines
2.9 KiB
Python
102 lines
2.9 KiB
Python
from __future__ import annotations
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
from types import SimpleNamespace
|
|
|
|
import pytest
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
|
|
|
|
from astrbot_sdk.errors import AstrBotError
|
|
from astrbot_sdk.runtime.handler_dispatcher import HandlerDispatcher
|
|
from astrbot_sdk.star import Star
|
|
|
|
|
|
class _DummyEvent:
|
|
def __init__(self) -> None:
|
|
self.replies: list[str] = []
|
|
|
|
async def reply(self, message: str) -> None:
|
|
self.replies.append(message)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_handle_error_fallback_does_not_instantiate_star(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
) -> None:
|
|
async def _fake_default_on_error(error: Exception, event, ctx) -> None:
|
|
del ctx
|
|
await event.reply(str(error))
|
|
|
|
def _fail_init(self) -> None:
|
|
raise AssertionError("Star should not be instantiated for fallback on_error")
|
|
|
|
monkeypatch.setattr(Star, "default_on_error", staticmethod(_fake_default_on_error))
|
|
monkeypatch.setattr(Star, "__init__", _fail_init)
|
|
|
|
dispatcher = HandlerDispatcher(
|
|
plugin_id="plugin", peer=SimpleNamespace(), handlers=[]
|
|
)
|
|
event = _DummyEvent()
|
|
|
|
await dispatcher._handle_error(
|
|
object(),
|
|
RuntimeError("boom"),
|
|
event,
|
|
SimpleNamespace(),
|
|
)
|
|
|
|
assert event.replies == ["boom"]
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_default_on_error_formats_astrbot_error_reply() -> None:
|
|
event = _DummyEvent()
|
|
error = AstrBotError.invalid_input(
|
|
"bad payload",
|
|
hint="check payload",
|
|
docs_url="https://example.com/docs",
|
|
details={"b": 2, "a": 1},
|
|
)
|
|
|
|
await Star.default_on_error(error, event, SimpleNamespace())
|
|
|
|
assert len(event.replies) == 1
|
|
assert "check payload" in event.replies[0]
|
|
assert "https://example.com/docs" in event.replies[0]
|
|
assert '"a": 1' in event.replies[0]
|
|
assert '"b": 2' in event.replies[0]
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_default_on_error_replies_generic_message_for_unknown_errors() -> None:
|
|
event = _DummyEvent()
|
|
|
|
await Star.default_on_error(RuntimeError("boom"), event, SimpleNamespace())
|
|
|
|
assert len(event.replies) == 1
|
|
assert event.replies[0]
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_on_error_does_not_dispatch_via_subclass_default_on_error() -> None:
|
|
class PluginWithShadowedDefault(Star):
|
|
async def default_on_error(self, error: Exception, event, ctx) -> None:
|
|
del error, event, ctx
|
|
raise AssertionError(
|
|
"Star.on_error should not virtual-dispatch default_on_error"
|
|
)
|
|
|
|
expected_event = _DummyEvent()
|
|
actual_event = _DummyEvent()
|
|
|
|
await Star.default_on_error(RuntimeError("boom"), expected_event, SimpleNamespace())
|
|
await PluginWithShadowedDefault().on_error(
|
|
RuntimeError("boom"),
|
|
actual_event,
|
|
SimpleNamespace(),
|
|
)
|
|
|
|
assert actual_event.replies == expected_event.replies
|