Created
July 5, 2016 07:37
-
-
Save anonymous/789e66b8ca009dfc0ee53df4e9d584fc to your computer and use it in GitHub Desktop.
Wrapping of python's incoherent error messages
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class RpcException(Exception): | |
""" An RPC-specific exception. Details should be in the message """ | |
pass | |
def rpc_call(target, data, fn_prefix='_cmd_'): | |
""" Common logic for exposing several methods from a class as RPC | |
(at the level after the data-parsing). | |
Note: likely only works in CPython. """ | |
if not isinstance(data, dict): | |
raise RpcException('`data` is not a dict') | |
try: | |
cmd = data.pop('cmd') | |
except KeyError as e: | |
raise RpcException('`cmd` is not specified in the data', e) | |
try: | |
fn = getattr(target, '%s%s' % (fn_prefix, cmd)) | |
except AttributeError as e: | |
raise RpcException('command %r not found' % (cmd,), e) | |
_log.debug("Calling: %r, %r", fn, data) | |
try: | |
return fn(**data) | |
except TypeError as e: | |
# More-sane-than-default processing of a case `parameter ... was not specified` (py2) | |
if fn.func_code.co_flags & 0x04: | |
# it accepts `*ar`, so not the case | |
raise | |
f_vars = fn.func_code.co_varnames | |
f_defvars_count = len(fn.func_defaults) | |
f_posvars = f_vars[:-f_defvars_count] | |
extra_args = list(set(data.keys()) - set(f_vars)) | |
# TODO: `inspect.getargspec` | |
# XXX: it catches `self` in a bound method as required. (also, classmethods?) | |
missing_args = list(set(f_posvars) - set(data.keys())) | |
if missing_args: # is the case, raise it verbosely. | |
msg = "Required argument(s) not specified: %s" % ( | |
', '.join(missing_args),) | |
if extra_args: | |
msg += "; additionally, there are extraneous arguments: %s" % ( | |
', '.join(extra_args)) | |
raise TypeError(msg, e) | |
raise |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment