Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions ophyd/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ def exception(self, timeout=None):
return self._exception

@tracer.start_as_current_span(f"{_TRACE_PREFIX} wait")
def wait(self, timeout=None):
def wait(self, timeout=None, timeout_exception=None):
"""
Block until the action completes.

Expand All @@ -451,6 +451,11 @@ def wait(self, timeout=None):
timeout: Union[Number, None], optional
If None (default) wait indefinitely until the status finishes.

timeout_exception: Exception, optional
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be the class to raise not an instantiated exception.

If None (default), WaitTimeoutError will be raised if the status
does not complete within ``timeout``. If this is set to an Exception,
that exception will be raised instead.

Raises
------
WaitTimeoutError
Expand All @@ -465,9 +470,14 @@ def wait(self, timeout=None):
indicates that the action itself raised ``TimeoutError``, distinct
from ``WaitTimeoutError`` above.
"""
exception_to_raise = (
Copy link
Contributor

Choose a reason for hiding this comment

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

Creating the exception grabs things about the current stack, we should not create it until we need it.

timeout_exception
if isinstance(timeout_exception, Exception)
Copy link
Member

Choose a reason for hiding this comment

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

One thing to consider: we might want to fail loudly with a TypeError if the user passes a non-exception non-None here.

else WaitTimeoutError(f"Status {self!r} has not completed yet.")
)
_set_trace_attributes(trace.get_current_span(), self._trace_attributes)
if not self._event.wait(timeout=timeout):
raise WaitTimeoutError(f"Status {self!r} has not completed yet.")
raise exception_to_raise
if self._exception is not None:
raise self._exception

Expand Down
9 changes: 9 additions & 0 deletions ophyd/tests/test_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,15 @@ def test_wait_timeout():
with pytest.raises(WaitTimeoutError):
st.exception(0.01)

custom_exception = ValueError("My custom exception")
with pytest.raises(ValueError) as exc:
st.wait(0.01, timeout_exception=custom_exception)
assert exc.value is custom_exception

# Wrong input should raise WaitTimeoutError
with pytest.raises(WaitTimeoutError):
st.wait(0.01, timeout_exception="Not an exception")


def test_status_timeout():
"""
Expand Down