Permalink
Browse files

Add error flags for throwing errors back into generator

The following code demonstrates this behavior. As foo.on_error is
'throw_last' the on_error_1 handler is executed as well as on_error_2
which is the exception throwed back to the bar handler.

from circuits import Event, Component, handler, Debugger
import pytest

class foo(Event):
	on_error = 'throw_last'

class bar(Event):
	pass

class Foo(Component):
	@handler('foo', priority=2)
	def _on_error_1(self):
		raise ValueError('test')

	@handler('foo', priority=1)
	def _on_error_2(self):
		raise ValueError('test2')

	def bar(self):
		with pytest.raises(ValueError) as exc:
			x = yield self.call(foo())
		assert exc.value.args[0] == 'test2'
		print('DONE')

x = Foo()
x += Debugger()
x.fire(bar())
x.run()
  • Loading branch information...
1 parent 2a57dac commit 1d52151a14ba06690ccac0829983ccb7138818eb @spaceone spaceone committed Feb 12, 2017
Showing with 10 additions and 4 deletions.
  1. +1 −1 circuits/core/events.py
  2. +9 −3 circuits/core/manager.py
@@ -19,7 +19,7 @@ class Event(object):
waitingHandlers = 0
# Behaviour for handling errors:
- # One of "abort", "igore" (default)
+ # One of "abort", "ingore" (default), "throw_first", "throw_last"
on_error = None
@classmethod
@@ -707,9 +707,9 @@ def _dispatcher(self, event, channels, remaining): # noqa
event.reduce_time_left(TIMEOUT)
if err is not None:
- if event.on_error == "abort":
+ if event.on_error in ("abort", "throw_first"):
break
- elif event.on_error == "ignore":
+ elif event.on_error in ("ignore", "throw_last"):
continue
else:
continue
@@ -842,7 +842,13 @@ def processTask(self, event, task, parent=None): # noqa
# Done here, next() will StopIteration anyway
self.unregisterTask((event, task, parent))
# We are in a callEvent
- value = parent.send(value.value)
+ if value.value.event.on_error in ('throw_first', 'throw_last') and value.value.errors:
+ error = value.value.value
+ if not isinstance(error, list):
+ error = [error]
+ parent.throw(*error[-1])
+ else:
+ value = parent.send(value.value)
if isinstance(value, GeneratorType):
# We loose a yield but we gain one,
# we don't need to change

0 comments on commit 1d52151

Please sign in to comment.