"""Exceptions native to solana-py.""" from typing import Callable, Any class SolanaExceptionBase(Exception): """Base class for Solana-py exceptions.""" def __init__(self, exc: Exception, func: Callable[[Any], Any], *args: Any, **kwargs: Any) -> None: """Init.""" super().__init__() self.error_msg = self._build_error_message(exc, func, *args, **kwargs) @staticmethod def _build_error_message( exc: Exception, func: Callable[[Any], Any], *args: Any, **kwargs: Any # pylint: disable=unused-argument ) -> str: return f"{type(exc)} raised in {func} invokation" class SolanaRpcException(SolanaExceptionBase): """Class for Solana-py RPC exceptions.""" @staticmethod def _build_error_message(exc: Exception, func: Callable[[Any], Any], *args: Any, **kwargs: Any) -> str: rpc_method = args[1] return f'{type(exc)} raised in "{rpc_method}" endpoint request' def handle_exceptions(internal_exception_cls, *exception_types_caught): """Decorator for handling non-async exception.""" def func_decorator(func): def argument_decorator(*args, **kwargs): try: return func(*args, **kwargs) except exception_types_caught as exc: raise internal_exception_cls(exc, func, *args, **kwargs) from exc return argument_decorator return func_decorator def handle_async_exceptions(internal_exception_cls, *exception_types_caught): """Decorator for handling async exception.""" def func_decorator(func): async def argument_decorator(*args, **kwargs): try: return await func(*args, **kwargs) except exception_types_caught as exc: raise internal_exception_cls(exc, func, *args, **kwargs) from exc return argument_decorator return func_decorator