Skip to content

Commit

Permalink
Add error flags for throwing errors back into generator
Browse files Browse the repository at this point in the history
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
spaceone committed Feb 12, 2017
1 parent 2a57dac commit 1d52151
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 4 deletions.
2 changes: 1 addition & 1 deletion circuits/core/events.py
Expand Up @@ -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
Expand Down
12 changes: 9 additions & 3 deletions circuits/core/manager.py
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 1d52151

Please sign in to comment.