From 08cce15ef92fca8d5d4eddce51c056210cb03ba5 Mon Sep 17 00:00:00 2001 From: fawce Date: Tue, 31 Jul 2012 16:02:28 -0400 Subject: [PATCH] added name and message to exception message --- tests/test_exception_handling.py | 166 ++++++++++++++++---------- zipline/components/tradesimulation.py | 6 +- zipline/core/monitor.py | 3 + zipline/protocol.py | 8 +- zipline/test_algorithms.py | 28 +++++ 5 files changed, 143 insertions(+), 68 deletions(-) diff --git a/tests/test_exception_handling.py b/tests/test_exception_handling.py index 6b67c9db..b33a2acb 100644 --- a/tests/test_exception_handling.py +++ b/tests/test_exception_handling.py @@ -3,7 +3,7 @@ import zmq from unittest2 import TestCase from collections import defaultdict -from zipline.test_algorithms import ExceptionAlgorithm +from zipline.test_algorithms import ExceptionAlgorithm, DivByZeroAlgorithm from zipline.finance.trading import SIMULATION_STYLE from zipline.core.devsimulator import AddressAllocator from zipline.lines import SimulatedTrading @@ -54,7 +54,9 @@ class ExceptionTestCase(TestCase): output, _ = drain_zipline(self, zipline) self.assertEqual(len(output), 1) self.assertEqual(output[-1]['prefix'], 'EXCEPTION') - payload = output[-1]['payload']['stack'] + payload = output[-1]['payload'] + self.assertTrue(payload['date']) + del payload['date'] check(self, payload, INITIALIZE_TB) self.assertTrue(zipline.sim.ready()) @@ -79,12 +81,37 @@ class ExceptionTestCase(TestCase): self.assertEqual(len(output), 1) self.assertEqual(output[-1]['prefix'], 'EXCEPTION') - payload = output[-1]['payload']['stack'] + payload = output[-1]['payload'] + self.assertTrue(payload['date']) + del payload['date'] check(self, payload, HANDLE_DATA_TB) self.assertTrue(zipline.sim.ready()) self.assertFalse(zipline.sim.exception) + def test_zerodivision_exception_in_handle_data(self): + + # Simulation + # ---------- + self.zipline_test_config['algorithm'] = \ + DivByZeroAlgorithm( + self.zipline_test_config['sid'] + ) + + zipline = SimulatedTrading.create_test_zipline( + **self.zipline_test_config + ) + + output, _ = drain_zipline(self, zipline) + self.assertEqual(len(output), 5) + self.assertEqual(output[-1]['prefix'], 'EXCEPTION') + payload = output[-1]['payload'] + self.assertTrue(payload['date']) + del payload['date'] + check(self, payload, ZERO_DIV_TB) + + self.assertTrue(zipline.sim.ready()) + self.assertFalse(zipline.sim.exception) # TODO: # - define more zipline failure modes: exception in other @@ -94,66 +121,77 @@ class ExceptionTestCase(TestCase): INITIALIZE_TB =\ -[{'filename': '/zipline/core/component.py', - 'line': 'self._run()', - 'lineno': 204, - 'method': 'run'}, - {'filename': '/zipline/core/component.py', - 'line': 'self.loop()', - 'lineno': 195, - 'method': '_run'}, - {'filename': '/zipline/core/component.py', - 'line': 'self.do_work()', - 'lineno': 235, - 'method': 'loop'}, - {'filename': '/zipline/components/tradesimulation.py', - 'line': 'self.initialize_algo()', - 'lineno': 97, - 'method': 'do_work'}, - {'filename': '/zipline/components/tradesimulation.py', - 'line': 'self.do_op(self.algorithm.initialize)', - 'lineno': 80, - 'method': 'initialize_algo'}, - {'filename': '/zipline/components/tradesimulation.py', - 'line': 'callable_op(*args, **kwargs)', - 'lineno': 206, - 'method': 'do_op'}, - {'filename': '/zipline/test_algorithms.py', - 'line': 'raise Exception("Algo exception in initialize")', - 'lineno': 166, - 'method': 'initialize'}] - +{'message': 'Algo exception in initialize', + 'name': 'Exception', + 'stack': [{'filename': '/zipline/core/component.py', 'line': 'self._run()', 'lineno': 204, 'method': 'run'}, + {'filename': '/zipline/core/component.py', 'line': 'self.loop()', 'lineno': 195, 'method': '_run'}, + {'filename': '/zipline/core/component.py', 'line': 'self.do_work()', 'lineno': 235, 'method': 'loop'}, + {'filename': '/zipline/components/tradesimulation.py', + 'line': 'self.initialize_algo()', + 'lineno': 97, + 'method': 'do_work'}, + {'filename': '/zipline/components/tradesimulation.py', + 'line': 'self.do_op(self.algorithm.initialize)', + 'lineno': 80, + 'method': 'initialize_algo'}, + {'filename': '/zipline/components/tradesimulation.py', + 'line': 'callable_op(*args, **kwargs)', + 'lineno': 210, + 'method': 'do_op'}, + {'filename': '/zipline/test_algorithms.py', + 'line': 'raise Exception("Algo exception in initialize")', + 'lineno': 166, + 'method': 'initialize'}]} HANDLE_DATA_TB =\ -[{'filename': '/zipline/core/component.py', - 'line': 'self._run()', - 'lineno': 204, - 'method': 'run'}, - {'filename': '/zipline/core/component.py', - 'line': 'self.loop()', - 'lineno': 195, - 'method': '_run'}, - {'filename': '/zipline/core/component.py', - 'line': 'self.do_work()', - 'lineno': 235, - 'method': 'loop'}, - {'filename': '/zipline/components/tradesimulation.py', - 'line': 'self.process_event(event)', - 'lineno': 116, - 'method': 'do_work'}, - {'filename': '/zipline/components/tradesimulation.py', - 'line': 'self.run_algorithm()', - 'lineno': 164, - 'method': 'process_event'}, - {'filename': '/zipline/components/tradesimulation.py', - 'line': 'self.do_op(self.algorithm.handle_data, data)', - 'lineno': 186, - 'method': 'run_algorithm'}, - {'filename': '/zipline/components/tradesimulation.py', - 'line': 'callable_op(*args, **kwargs)', - 'lineno': 206, - 'method': 'do_op'}, - {'filename': '/zipline/test_algorithms.py', - 'line': 'raise Exception("Algo exception in handle_data")', - 'lineno': 187, - 'method': 'handle_data'}] +{ + 'message': 'Algo exception in handle_data', + 'name': 'Exception', + 'stack': [{'filename': '/zipline/core/component.py', 'line': 'self._run()', 'lineno': 204, 'method': 'run'}, + {'filename': '/zipline/core/component.py', 'line': 'self.loop()', 'lineno': 195, 'method': '_run'}, + {'filename': '/zipline/core/component.py', 'line': 'self.do_work()', 'lineno': 235, 'method': 'loop'}, + {'filename': '/zipline/components/tradesimulation.py', + 'line': 'self.process_event(event)', + 'lineno': 116, + 'method': 'do_work'}, + {'filename': '/zipline/components/tradesimulation.py', + 'line': 'self.run_algorithm()', + 'lineno': 164, + 'method': 'process_event'}, + {'filename': '/zipline/components/tradesimulation.py', + 'line': 'self.do_op(self.algorithm.handle_data, data)', + 'lineno': 186, + 'method': 'run_algorithm'}, + {'filename': '/zipline/components/tradesimulation.py', + 'line': 'callable_op(*args, **kwargs)', + 'lineno': 210, + 'method': 'do_op'}, + {'filename': '/zipline/test_algorithms.py', + 'line': 'raise Exception("Algo exception in handle_data")', + 'lineno': 187, + 'method': 'handle_data'}]} + + +ZERO_DIV_TB= \ +{'message': 'integer division or modulo by zero', + 'name': 'ZeroDivisionError', + 'stack': [{'filename': '/zipline/core/component.py', 'line': 'self._run()', 'lineno': 204, 'method': 'run'}, + {'filename': '/zipline/core/component.py', 'line': 'self.loop()', 'lineno': 195, 'method': '_run'}, + {'filename': '/zipline/core/component.py', 'line': 'self.do_work()', 'lineno': 235, 'method': 'loop'}, + {'filename': '/zipline/components/tradesimulation.py', + 'line': 'self.process_event(event)', + 'lineno': 116, + 'method': 'do_work'}, + {'filename': '/zipline/components/tradesimulation.py', + 'line': 'self.run_algorithm()', + 'lineno': 164, + 'method': 'process_event'}, + {'filename': '/zipline/components/tradesimulation.py', + 'line': 'self.do_op(self.algorithm.handle_data, data)', + 'lineno': 186, + 'method': 'run_algorithm'}, + {'filename': '/zipline/components/tradesimulation.py', + 'line': 'callable_op(*args, **kwargs)', + 'lineno': 210, + 'method': 'do_op'}, + {'filename': '/zipline/test_algorithms.py', 'line': '5/0', 'lineno': 218, 'method': 'handle_data'}]} diff --git a/zipline/components/tradesimulation.py b/zipline/components/tradesimulation.py index 60202854..aa8ca937 100644 --- a/zipline/components/tradesimulation.py +++ b/zipline/components/tradesimulation.py @@ -188,7 +188,11 @@ class TradeSimulationClient(Component): def exception_callback(self, exc_type, exc_value, exc_traceback): if self.results_socket: log.info("Sending exception frame") - msg = zp.EXCEPTION_FRAME(exc_traceback) + msg = zp.EXCEPTION_FRAME( + exc_traceback, + exc_type.__name__, + exc_value.message + ) self.out_socket.send(msg) def do_op(self, callable_op, *args, **kwargs): diff --git a/zipline/core/monitor.py b/zipline/core/monitor.py index 4ac138b7..c21cdf06 100644 --- a/zipline/core/monitor.py +++ b/zipline/core/monitor.py @@ -145,6 +145,9 @@ class Controller(object): self.state = CONTROL_STATES.INIT + # TODO: keep the exitfunc? the corresponding override on clean + # exit is commented out currently. + # # Interpreter SIDE EFFECT # ----------------------- # The last breathe of the interpreter will assume that we've diff --git a/zipline/protocol.py b/zipline/protocol.py index 703787e8..7aa503d7 100644 --- a/zipline/protocol.py +++ b/zipline/protocol.py @@ -522,7 +522,7 @@ def convert_transactions(transactions): def RISK_FRAME(risk): return BT_UPDATE_FRAME('RISK', risk) -def EXCEPTION_FRAME(exception_tb): +def EXCEPTION_FRAME(exception_tb, name, message): stack_list = traceback.extract_tb(exception_tb) rlist = [] for stack in stack_list: @@ -535,8 +535,10 @@ def EXCEPTION_FRAME(exception_tb): } rlist.append(rstack) result = { - 'date' : epoch_now(), - 'stack' : rlist + 'date' : epoch_now(), + 'stack' : rlist, + 'name' : name, + 'message' : message } return BT_UPDATE_FRAME('EXCEPTION', result) diff --git a/zipline/test_algorithms.py b/zipline/test_algorithms.py index d66cdef0..68f3d160 100644 --- a/zipline/test_algorithms.py +++ b/zipline/test_algorithms.py @@ -194,6 +194,34 @@ class ExceptionAlgorithm(object): else: return [self.sid] +class DivByZeroAlgorithm(): + + def __init__(self, sid): + self.sid = sid + self.incr = 0 + + def initialize(self): + pass + + def set_order(self, order_callable): + pass + + def set_logger(self, logger): + pass + + def set_portfolio(self, portfolio): + pass + + def handle_data(self, data): + self.incr += 1 + if self.incr > 4: + 5/0 + pass + + def get_sid_filter(self): + return [self.sid] + + class TestPrintAlgorithm(): def __init__(self, sid):