Skip to content

Commit 517837d

Browse files
committed
Ensure data handling exceptions are propogated to callers
For both camonitor and caget we have to do data conversion on callbacks called from ctypes, so this fix catches any conversion errors and propogates them back to the original caller.
1 parent bf6d7b2 commit 517837d

1 file changed

Lines changed: 21 additions & 5 deletions

File tree

cothread/catools.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -325,8 +325,15 @@ def __on_event(args):
325325
self = args.usr
326326

327327
if args.status == cadef.ECA_NORMAL:
328-
# Good data: extract value from the dbr.
329-
value = self.dbr_to_value(args.raw_dbr, args.type, args.count)
328+
# Good data: extract value from the dbr. Note that this can fail,
329+
# for example if there is malformed UTF-8 in the result.
330+
try:
331+
value = self.dbr_to_value(args.raw_dbr, args.type, args.count)
332+
except:
333+
# If there is an error, bypass update merging and force this
334+
# exception tuple into the processing chain.
335+
self.__Callback(self.__signal, sys.exc_info())
336+
return
330337
elif self.notify_disconnect:
331338
# Something is wrong: let the subscriber know, if they've requested
332339
# disconnect nofication.
@@ -361,7 +368,12 @@ def __signal(self, value):
361368
self.__update_count = 0
362369

363370
try:
364-
self.callback(value)
371+
if isinstance(value, tuple):
372+
# This should only happen if the asynchronous callback
373+
# caught an exception for us to re-raise here.
374+
py23.raise_with_traceback(value)
375+
else:
376+
self.callback(value)
365377
except:
366378
# We try and be robust about exceptions in handlers, but to
367379
# prevent a perpetual storm of exceptions, we close the
@@ -583,8 +595,12 @@ def _caget_event_handler(args):
583595
ctypes.pythonapi.Py_DecRef(args.usr)
584596

585597
if args.status == cadef.ECA_NORMAL:
586-
cothread.Callback(done.Signal, dbr_to_value(
587-
args.raw_dbr, args.type, args.count))
598+
try:
599+
value = dbr_to_value(args.raw_dbr, args.type, args.count)
600+
except:
601+
cothread.Callback(done.SignalException, sys.exc_info()[1])
602+
else:
603+
cothread.Callback(done.Signal, value)
588604
else:
589605
cothread.Callback(done.SignalException, ca_nothing(pv, args.status))
590606

0 commit comments

Comments
 (0)