Skip to content

Commit

Permalink
added better error message and test
Browse files Browse the repository at this point in the history
  • Loading branch information
evalott100 committed Feb 16, 2024
1 parent f647db9 commit 170dbba
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 6 deletions.
12 changes: 10 additions & 2 deletions src/ophyd_async/core/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from bluesky.protocols import HasName
from bluesky.run_engine import call_in_bluesky_event_loop

from .utils import DEFAULT_TIMEOUT, wait_for_connection
from .utils import DEFAULT_TIMEOUT, NotConnected, wait_for_connection


class Device(HasName):
Expand Down Expand Up @@ -173,4 +173,12 @@ async def __aexit__(self, type, value, traceback):

def __exit__(self, type_, value, traceback):
self._objects_on_exit = self._caller_locals()
return call_in_bluesky_event_loop(self._on_exit())
try:
fut = call_in_bluesky_event_loop(self._on_exit())
except RuntimeError:
raise NotConnected(
"Could not connect devices. Is the bluesky event loop running? See "
"https://blueskyproject.io/ophyd-async/main/"
"user/explanations/event-loop-choice.html for more info."
)
return fut
55 changes: 51 additions & 4 deletions tests/core/test_device_collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,26 @@
from ophyd_async.core import DEFAULT_TIMEOUT, Device, DeviceCollector, NotConnected


class Dummy(Device):
class FailingDevice(Device):
async def connect(self, sim: bool = False, timeout=DEFAULT_TIMEOUT):
raise AttributeError()


def test_device_collector_handles_top_level_errors(RE, caplog):
class WorkingDevice(Device):
connected = False

async def connect(self, sim: bool = True, timeout=DEFAULT_TIMEOUT):
self.connected = True
return await super().connect(sim=True)

async def set(self, new_position: float): ...


async def test_device_collector_handles_top_level_errors(caplog):
caplog.set_level(10)
with pytest.raises(NotConnected) as exc:
with DeviceCollector():
_ = Dummy("somename")
async with DeviceCollector():
_ = FailingDevice("somename")

assert not exc.value.__cause__

Expand All @@ -25,3 +35,40 @@ def test_device_collector_handles_top_level_errors(RE, caplog):

assert len(device_log) == 1
device_log[0].levelname == "ERROR"


def test_device_connector_sync_no_run_engine_raises_error():
with pytest.raises(NotConnected) as e:
with DeviceCollector():
working_device = WorkingDevice("somename")
assert e.value._errors == (
"Could not connect devices. Is the bluesky event loop running? See "
"https://blueskyproject.io/ophyd-async/main/"
"user/explanations/event-loop-choice.html for more info."
)
assert not working_device.connected


def test_device_connector_sync_run_engine_created_connects(RE):
with DeviceCollector():
working_device = WorkingDevice("somename")

assert working_device.connected


"""
# TODO: Once passing a loop into the run-engine selector works, this should pass
async def test_device_connector_async_run_engine_same_event_loop():
async with DeviceCollector(sim=True):
sim_motor = motor.Motor("BLxxI-MO-TABLE-01:X")
RE = RunEngine(loop=asyncio.get_running_loop())
def my_plan():
sim_motor.move(3.14)
return
RE(my_plan())
assert await sim_motor.readback.get_value() == 3.14
"""

0 comments on commit 170dbba

Please sign in to comment.