66from typing import Any , TypeVar
77
88from models_library .rabbitmq_basic_types import RPCMethodName
9- from pydantic import SecretStr
109
1110from ..logging_utils import log_context
1211from ._errors import RPCServerError
1312
1413DecoratedCallable = TypeVar ("DecoratedCallable" , bound = Callable [..., Any ])
1514
15+ # NOTE: this is equivalent to http access logs
1616_logger = logging .getLogger ("rpc.access" )
1717
18- _RPC_CUSTOM_ENCODER : dict [Any , Callable [[Any ], Any ]] = {
19- SecretStr : SecretStr .get_secret_value
20- }
18+
19+ def _create_func_msg (func , args : list [Any ], kwargs : dict [str , Any ]) -> str :
20+ msg = f"{ func .__name__ } ("
21+
22+ if args_msg := ", " .join (map (str , args )):
23+ msg += args_msg
24+
25+ if kwargs_msg := ", " .join ({f"{ name } ={ value } " for name , value in kwargs .items ()}):
26+ if args :
27+ msg += ", "
28+ msg += kwargs_msg
29+
30+ return f"{ msg } )"
2131
2232
2333@dataclass
2434class RPCRouter :
2535 routes : dict [RPCMethodName , Callable ] = field (default_factory = dict )
2636
27- def expose (self ) -> Callable [[DecoratedCallable ], DecoratedCallable ]:
28- def decorator (func : DecoratedCallable ) -> DecoratedCallable :
37+ def expose (
38+ self ,
39+ * ,
40+ reraise_if_error_type : tuple [type [Exception ], ...] | None = None ,
41+ ) -> Callable [[DecoratedCallable ], DecoratedCallable ]:
42+ def _decorator (func : DecoratedCallable ) -> DecoratedCallable :
2943 @functools .wraps (func )
30- async def wrapper (* args , ** kwargs ):
44+ async def _wrapper (* args , ** kwargs ):
45+
3146 with log_context (
47+ # NOTE: this is intentionally analogous to the http access log traces.
48+ # To change log-level use getLogger("rpc.access").set_level(...)
3249 _logger ,
3350 logging .INFO ,
34- msg = f"calling { func .__name__ } with { args } , { kwargs } " ,
51+ msg = f"RPC call { _create_func_msg (func , args , kwargs )} " ,
52+ log_duration = True ,
3553 ):
3654 try :
3755 return await func (* args , ** kwargs )
56+
3857 except asyncio .CancelledError :
3958 _logger .debug ("call was cancelled" )
4059 raise
60+
4161 except Exception as exc : # pylint: disable=broad-except
62+ if reraise_if_error_type and type (exc ) in reraise_if_error_type :
63+ raise
64+
4265 _logger .exception ("Unhandled exception:" )
4366 # NOTE: we do not return internal exceptions over RPC
4467 raise RPCServerError (
@@ -47,7 +70,7 @@ async def wrapper(*args, **kwargs):
4770 msg = f"{ exc } " ,
4871 ) from None
4972
50- self .routes [RPCMethodName (func .__name__ )] = wrapper
73+ self .routes [RPCMethodName (func .__name__ )] = _wrapper
5174 return func
5275
53- return decorator
76+ return _decorator
0 commit comments