diff --git a/nanobot/channels/signal.py b/nanobot/channels/signal.py index e40f5197e..64e099f4d 100644 --- a/nanobot/channels/signal.py +++ b/nanobot/channels/signal.py @@ -506,6 +506,7 @@ class SignalChannel(BaseChannel): if "error" in response: self.logger.error(f"Error sending Signal message: {response['error']}") + raise RuntimeError(f"signal-cli send failed: {response['error']}") else: self.logger.debug( f"Signal message sent, timestamp: {response.get('result', {}).get('timestamp')}" diff --git a/tests/channels/test_signal_channel.py b/tests/channels/test_signal_channel.py index 56a35b94b..214117176 100644 --- a/tests/channels/test_signal_channel.py +++ b/tests/channels/test_signal_channel.py @@ -1217,13 +1217,14 @@ class TestSend: assert "+19995550001" in stopped @pytest.mark.asyncio - async def test_send_logs_daemon_error_without_raising(self): + async def test_send_raises_on_daemon_error(self): + # _send_http_request turns every exception into {"error": ...}, so this branch + # is the only place ChannelManager retry can be triggered — must raise. ch = _make_channel() - # The daemon returns {"error": {...}} in the JSON body — this is not a Python - # exception; send() logs it but does not raise (only HTTP-level exceptions raise). ch._http = _FakeHTTPClient(default_response={"error": {"message": "fail"}}) msg = OutboundMessage(channel="signal", chat_id="+19995550001", content="hello") - await ch.send(msg) # must not raise + with pytest.raises(RuntimeError, match="signal-cli send failed"): + await ch.send(msg) # ---------------------------------------------------------------------------