From 85ab3e2cd7015a6f9f28492ab1df384c4c93bd8a Mon Sep 17 00:00:00 2001 From: Jacques Wagener Date: Tue, 16 Oct 2018 19:49:24 +0200 Subject: [PATCH] Add better exceptions message for failing transactions. --- bin/vyper-run | 7 +++++++ vdb/debug_computation.py | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/bin/vyper-run b/bin/vyper-run index 39be663..b739dde 100755 --- a/bin/vyper-run +++ b/bin/vyper-run @@ -1,5 +1,7 @@ #!/usr/bin/env python3.6 import argparse +import sys +import os import vyper from collections import Counter from pprint import pprint @@ -20,6 +22,11 @@ from web3 import ( Web3, ) +sys.tracebacklimit = 0 +tb_limit = os.environ.get('VYPER_TRACEBACK_LIMIT') +if tb_limit: + sys.tracebacklimit = int(tb_limit) + aparser = argparse.ArgumentParser(description='Vyper {0} quick CLI runner'.format(vyper.__version__)) aparser.add_argument('input_file', help='Vyper sourcecode to run') aparser.add_argument('call_list', help='call list, without parameters: func, with parameters func(1, 2, 3). Semicolon separated') diff --git a/vdb/debug_computation.py b/vdb/debug_computation.py index 8b67a82..a5e1be8 100644 --- a/vdb/debug_computation.py +++ b/vdb/debug_computation.py @@ -5,6 +5,20 @@ from evm.exceptions import ( Halt, ) from vdb.vdb import VyperDebugCmd +from evm.exceptions import VMError +from vyper.exceptions import ParserException + + +class DebugVMError(VMError, ParserException): + lineno = None + col_offset = None + + def __init__(self, message, item=None, source_code=None): + self.message = message + if item is not None: + self.lineno, self.col_offset = item + if source_code is not None: + self.source_code = source_code.splitlines() class DebugComputation(ByzantiumComputation): @@ -27,10 +41,17 @@ class DebugComputation(ByzantiumComputation): return line_no @classmethod - def get_line_no(cls, pc): + def get_pos(cls, pc): pc_pos_map = cls.source_map['line_number_map']['pc_pos_map'] if pc in pc_pos_map: - return pc_pos_map[pc][0] + return pc_pos_map[pc] + + @classmethod + def get_line_no(cls, pc): + pos = cls.get_pos(pc) + if pos: + return pos[0] + return None @classmethod def is_breakpoint(cls, pc, continue_line_nos): @@ -72,6 +93,16 @@ class DebugComputation(ByzantiumComputation): try: opcode_fn(computation=computation) + except VMError as e: # re-raise with more details. + pos = cls.get_pos(pc_to_execute) + msg = e.args[0] + msg = "" if len(msg) == 0 else msg + # import ipdb; ipdb.set_trace() + raise DebugVMError( + message=msg, + item=pos, + source_code=cls.source_code + ) from e except Halt: break