diff --git a/vyper/codegen/expr.py b/vyper/codegen/expr.py index 5870e64e98..d5ca5aceee 100644 --- a/vyper/codegen/expr.py +++ b/vyper/codegen/expr.py @@ -26,6 +26,7 @@ from vyper.evm.address_space import DATA, IMMUTABLES, MEMORY, STORAGE, TRANSIENT from vyper.evm.opcodes import version_check from vyper.exceptions import ( + CodegenPanic, CompilerPanic, EvmVersionException, StructureException, @@ -33,6 +34,7 @@ TypeMismatch, UnimplementedException, VyperException, + tag_exceptions, ) from vyper.semantics.types import ( AddressT, @@ -79,7 +81,9 @@ def __init__(self, node, context): if fn is None: raise TypeCheckFailure(f"Invalid statement node: {type(node).__name__}", node) - self.ir_node = fn() + with tag_exceptions(node, fallback_exception_type=CodegenPanic): + self.ir_node = fn() + if self.ir_node is None: raise TypeCheckFailure(f"{type(node).__name__} node did not produce IR.\n", node) diff --git a/vyper/codegen/stmt.py b/vyper/codegen/stmt.py index cc7a603b7c..601597771c 100644 --- a/vyper/codegen/stmt.py +++ b/vyper/codegen/stmt.py @@ -24,7 +24,13 @@ from vyper.codegen.expr import Expr from vyper.codegen.return_ import make_return_stmt from vyper.evm.address_space import MEMORY, STORAGE -from vyper.exceptions import CompilerPanic, StructureException, TypeCheckFailure +from vyper.exceptions import ( + CodegenPanic, + CompilerPanic, + StructureException, + TypeCheckFailure, + tag_exceptions, +) from vyper.semantics.types import DArrayT, MemberFunctionT from vyper.semantics.types.function import ContractFunctionT from vyper.semantics.types.shortcuts import INT256_T, UINT256_T @@ -39,7 +45,8 @@ def __init__(self, node: vy_ast.VyperNode, context: Context) -> None: raise TypeCheckFailure(f"Invalid statement node: {type(node).__name__}") with context.internal_memory_scope(): - self.ir_node = fn() + with tag_exceptions(node, fallback_exception_type=CodegenPanic): + self.ir_node = fn() if self.ir_node is None: raise TypeCheckFailure("Statement node did not produce IR") diff --git a/vyper/exceptions.py b/vyper/exceptions.py index 993c0a85eb..4846b1c3b1 100644 --- a/vyper/exceptions.py +++ b/vyper/exceptions.py @@ -1,3 +1,4 @@ +import contextlib import copy import textwrap import types @@ -322,8 +323,9 @@ class VyperInternalException(_BaseVyperException): def __str__(self): return ( - f"{self.message}\n\nThis is an unhandled internal compiler error. " - "Please create an issue on Github to notify the developers.\n" + f"{super().__str__()}\n\n" + "This is an unhandled internal compiler error. " + "Please create an issue on Github to notify the developers!\n" "https://github.com/vyperlang/vyper/issues/new?template=bug.md" ) @@ -354,3 +356,17 @@ class TypeCheckFailure(VyperInternalException): class InvalidABIType(VyperInternalException): """An internal routine constructed an invalid ABI type""" + + +@contextlib.contextmanager +def tag_exceptions( + node, fallback_exception_type=CompilerPanic, fallback_message="unhandled exception" +): + try: + yield + except _BaseVyperException as e: + if not e.annotations and not e.lineno: + raise e.with_annotation(node) from None + raise e from None + except Exception as e: + raise fallback_exception_type(fallback_message, node) from e diff --git a/vyper/semantics/analysis/common.py b/vyper/semantics/analysis/common.py index 9d35aef2bd..198cffca5d 100644 --- a/vyper/semantics/analysis/common.py +++ b/vyper/semantics/analysis/common.py @@ -1,17 +1,6 @@ -import contextlib from typing import Tuple -from vyper.exceptions import StructureException, VyperException - - -@contextlib.contextmanager -def tag_exceptions(node): - try: - yield - except VyperException as e: - if not e.annotations and not e.lineno: - raise e.with_annotation(node) from None - raise e from None +from vyper.exceptions import StructureException, tag_exceptions class VyperNodeVisitorBase: