python - Is exception-propagating decorator a good pattern? -
well-defined custom exceptions more informative builtin ones; e.g. ageerror
more valueerror
. in general try use former when can. consequence of this, code littered lots of raise foo bar
boilerplate propagate custom exception. here example of mean. without using custom exceptions, i'd write:
class person: def set_age(self, age_as_string): self.age = int(age_as_string)
this may raise either typeerror
or valueerror
, since caller handle it, one-liner fine.
but use custom exceptions, need boilerplate:
class ageerror(exception): pass class person: def set_age(self, age_as_string): try: self.age = int(age_as_string) except (typeerror, valueerror) e: raise ageerror e
this more informative caller's point of view, costs 300% more code (just counting method body) , obscures main business of set_age
.
is there way have best of both worlds? tried googling solutions problem doesn't seem discussed @ all. solution come use exception-propagating decorator, trivial write wonderful contextlib
(and little less trivial if need implement hand):
from contextlib import contextmanager @contextmananer def raise_from(to_catch, to_raise): try: yield except to_catch e: raise to_raise e
now need one-extra line, doesn't obscure business logic, , makes error-handling logic more obvious (and it's smart-looking):
class person: @raise_from(to_catch=(typeerror, valueerror), to_raise=ageerror) def set_age(self, age_as_string): self.age = int(age_as_string)
so i'm quite happy solution. since it's unlikely there still exists unsolved problem easy solution this, i'm worried may missing something. there disadvantages using raise_from
decorator haven't considered? or need reduce raise foo bar
boilerplate indication i'm doing wrong?
Comments
Post a Comment