Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Propagate exceptions in AndStatus and Signal.set to the user #1230

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
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
22 changes: 14 additions & 8 deletions ophyd/signal.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ def trigger(self):
# NOTE: this is a no-op that exists here for bluesky purposes
# it may need to be moved in the future
d = Status(self)
d._finished()
d.set_finished()
return d

def wait_for_connection(self, timeout=0.0):
Expand Down Expand Up @@ -394,10 +394,12 @@ def set(self, value, *, timeout=None, settle_time=None, **kwargs):
)

def set_thread():
_exception = None

try:
self._set_and_wait(value, timeout, **kwargs)
except TimeoutError:
success = False
except TimeoutError as e:
_exception = e
self.log.warning(
"%s: _set_and_wait(value=%s, timeout=%s, atol=%s, rtol=%s, kwargs=%s)",
self.name,
Expand All @@ -407,8 +409,8 @@ def set_thread():
self.rtolerance,
kwargs,
)
except Exception:
success = False
except Exception as e:
_exception = e
self.log.exception(
"%s: _set_and_wait(value=%s, timeout=%s, atol=%s, rtol=%s, kwargs=%s)",
self.name,
Expand All @@ -419,7 +421,6 @@ def set_thread():
kwargs,
)
else:
success = True
self.log.debug(
"%s: _set_and_wait(value=%s, timeout=%s, atol=%s, rtol=%s, kwargs=%s) succeeded => %s",
self.name,
Expand All @@ -439,7 +440,12 @@ def set_thread():
th = self._set_thread
# these two must be in this order to avoid a race condition
self._set_thread = None
st._finished(success=success)

if _exception is not None:
st.set_exception(_exception)
else:
st.set_finished()

del th

if self._set_thread is not None:
Expand Down Expand Up @@ -2247,7 +2253,7 @@ def set(self, value, *, timeout=DEFAULT_WRITE_TIMEOUT, settle_time=None):
st = Status(self, timeout=timeout, settle_time=settle_time)

def put_callback(**kwargs):
st._finished(success=True)
st.set_finished()

self.put(value, use_complete=True, callback=put_callback)
return st
Expand Down
15 changes: 6 additions & 9 deletions ophyd/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import threading
import time
from collections import deque
from functools import partial
from logging import LoggerAdapter
from warnings import warn

Expand Down Expand Up @@ -593,13 +592,13 @@ def inner(status):
# At least one is done.
# If it failed, do not wait for the second one.
if (not l_success) and l_done:
self._finished(success=False)
self.set_exception(self.left.exception())
elif (not r_success) and r_done:
self._finished(success=False)
self.set_exception(self.right.exception())

elif l_success and r_success and l_done and r_done:
# Both are done, successfully.
self._finished(success=True)
self.set_finished()
# Else one is done, successfully, and we wait for #2,
# when this function will be called again.

Expand Down Expand Up @@ -793,7 +792,7 @@ def check_value(self, *args, **kwargs):

# If successfull indicate completion
if success:
self._finished(success=True)
self.set_finished()

def set_finished(self):
"""
Expand Down Expand Up @@ -863,9 +862,7 @@ def __init__(
f"Stability time ({stability_time}) must be less than full status timeout ({timeout})"
)
self._stability_time = stability_time
self._stable_timer = threading.Timer(
self._stability_time, partial(self._finished, success=True)
)
self._stable_timer = threading.Timer(self._stability_time, self.set_finished)

# Start timeout thread in the background
super().__init__(
Expand All @@ -891,7 +888,7 @@ def check_value(self, *args, **kwargs):
else:
self._stable_timer.cancel()
self._stable_timer = threading.Timer(
self._stability_time, partial(self._finished, success=True)
self._stability_time, self.set_finished
)

# Do not fail silently
Expand Down
Loading