|
@@ -96,10 +96,8 @@ class RequestHandler(object):
|
|
|
def pop_generator(self):
|
|
|
"""Removes the top-of-stack generator from the generator stack."""
|
|
|
# Pop the generator itself.
|
|
|
- gen = self.generator_stack.pop()
|
|
|
-
|
|
|
+ self.generator_stack.pop()
|
|
|
# print('Popped generator %s. Generator count: %d' % (gen, len(self.generator_stack)))
|
|
|
-
|
|
|
# Pop any exception handlers defined by the generator.
|
|
|
top_of_stack_index = len(self.generator_stack)
|
|
|
while len(self.exception_handlers) > 0:
|
|
@@ -143,38 +141,37 @@ class RequestHandler(object):
|
|
|
def handle_exception(self, exception):
|
|
|
"""Handles the given exception. A Boolean is returned that tells if
|
|
|
the exception was handled."""
|
|
|
-
|
|
|
- print('Exception thrown from %s: %s' % (str(self.generator_stack[-1]), str(exception)))
|
|
|
- if len(self.exception_handlers) == 0:
|
|
|
- # Yep, we're hosed. Make sure the caller knows this.
|
|
|
- # Also, clean up.
|
|
|
- self.generator_stack = []
|
|
|
- self.exception_handlers = []
|
|
|
- return False
|
|
|
-
|
|
|
- # Pop the top-of-stack exception handler.
|
|
|
- stack_index, handlers = self.exception_handlers.pop()
|
|
|
-
|
|
|
- # Try to find an applicable handler.
|
|
|
- applicable_handler = None
|
|
|
- for handled_type, handler in handlers:
|
|
|
- if isinstance(exception, handled_type):
|
|
|
- applicable_handler = handler
|
|
|
-
|
|
|
- if applicable_handler is None:
|
|
|
- # We couldn't find an applicable handler. All is lost.
|
|
|
- self.generator_stack = []
|
|
|
- self.exception_handlers = []
|
|
|
- return False
|
|
|
-
|
|
|
- # We handle exceptions by first clearing the current stack frame and
|
|
|
- # all of its children. Then, we place a dummy frame on the stack with
|
|
|
- # a single 'TAIL_CALL_ARGS' request. The next iteration will replace
|
|
|
- # the dummy frame by an actual frame.
|
|
|
- del self.generator_stack[stack_index:]
|
|
|
- self.generator_stack.append(
|
|
|
- (None, [('TAIL_CALL_ARGS', [applicable_handler, (exception,)])], False, [], False))
|
|
|
- return True
|
|
|
+ # print('Exception thrown from %s: %s' % (str(self.generator_stack[-1]), str(exception)))
|
|
|
+ while len(self.exception_handlers) > 0:
|
|
|
+ # Pop the top-of-stack exception handler.
|
|
|
+ stack_index, handlers = self.exception_handlers.pop()
|
|
|
+
|
|
|
+ # Try to find an applicable handler.
|
|
|
+ applicable_handler = None
|
|
|
+ for handled_type, handler in handlers:
|
|
|
+ if isinstance(exception, handled_type):
|
|
|
+ applicable_handler = handler
|
|
|
+
|
|
|
+ if applicable_handler is not None:
|
|
|
+ # We handle exceptions by first clearing the current stack frame and
|
|
|
+ # all of its children. Then, we place a dummy frame on the stack with
|
|
|
+ # a single 'TAIL_CALL_ARGS' request. The next iteration will replace
|
|
|
+ # the dummy frame by an actual frame.
|
|
|
+ del self.generator_stack[stack_index:]
|
|
|
+ self.generator_stack.append(
|
|
|
+ (None,
|
|
|
+ [('TAIL_CALL_ARGS', [applicable_handler, (exception,)])],
|
|
|
+ False,
|
|
|
+ [],
|
|
|
+ False))
|
|
|
+ return True
|
|
|
+
|
|
|
+ # We couldn't find an applicable exception handler, even after exhausting the
|
|
|
+ # entire exception handler stack. All is lost.
|
|
|
+ # Also, clean up after ourselves.
|
|
|
+ self.generator_stack = []
|
|
|
+ self.exception_handlers = []
|
|
|
+ return False
|
|
|
|
|
|
def pop_requests(self):
|
|
|
"""Tries to pop a batch of Modelverse _state_ requests from the
|