2

I'd like to write a function that basically adds a log entry in addition to raising a given Exception, e.g.

def logged_raise(exc, *args):
    try:
        raise exc(args)
    except exc:
        logging.exception(args)
        # Or something more complicated, e.g. printing the
        # stacktrace if loggig.isEnabledFor(logging.DEBUG)
        raise

And call logged_raise(MyException, 'some %s text', myvar)
instead of raise MyException('some %s text', myvar).

While this basically works, the traceback points to the raise exc(args) line in logged_raise instead of the logged_raise(MyException,...) call. Can this be fixed somehow?

Tobias Kienzler
  • 25,759
  • 22
  • 127
  • 221
  • Why would this need fixing? The traceback shows the full stack, so the parent call is part of it. – Martijn Pieters Sep 26 '13 at 11:19
  • Is this for Python 2 or 3, btw? – Martijn Pieters Sep 26 '13 at 11:20
  • If it makes a severe difference, Python 2, though I was hoping for an independent solution. As I said, it's not grave since as you stated the parent call is also in the trace, but it would be neater to have this method more behave like a monkeypatched `raise` – Tobias Kienzler Sep 26 '13 at 11:24
  • Well, you could still add that as answer, since others might be interested in a Python 3 solution. Then again, due to [other](http://stackoverflow.com/q/16058529/321973) [reasons](http://stackoverflow.com/a/18466972/321973) I'm considering switching to that anyway... **edit** But doesn't Python 2 also allow this just with a different syntax, i.e. `raise exc(...), None, tb`? – Tobias Kienzler Sep 26 '13 at 11:26
  • Actually, you can in Python 2 as well. Not sure when I'll have time but I'll write something up when I do. – Martijn Pieters Sep 26 '13 at 11:27
  • I'll appreciate that - I did already write some code using `traceback.extract_stack()[:-1]`, but I'm not sure how to turn that into a `raise`-able traceback... – Tobias Kienzler Sep 26 '13 at 11:29
  • 1
    `traceback.extract_stack` doesn't return anything useful. You want a `traceback` object (a built-in type) but you cannot create one yourself. These objects are read-only as well. I am not yet convinced what you want can be done *at all* (Python 2 or 3). – Martijn Pieters Sep 26 '13 at 12:01
  • You're probably right, I guess the only alternative would be replacing [sys.excepthook](http://docs.python.org/2/library/sys.html#sys.__excepthook__) as suggested [here](http://stackoverflow.com/a/1029342/321973) and keeping in mind [that this won't work for threads](http://stackoverflow.com/a/9929970/321973) - this would result in **all** _uncaught_ exceptions being logged, which is however not exactly what I may want... **edit** Indeed what I want to do seems impossible: http://stackoverflow.com/a/6411333/321973 – Tobias Kienzler Sep 26 '13 at 12:02
  • 1
    Well, you can always filter some. Note that locals are visible in the stack trace for example; Zope looks for `__traceback_info__` locals in the stack and displays those with the stack trace. Very useful when debugging.. – Martijn Pieters Sep 26 '13 at 12:06
  • I don't see how this is necessary, but if you simply just want to display a different message, you can raise a system exit (no message is displayed) and print your own message. That is not at all an elegant solution, but it should solve your issue. A better solution would be to just overwrite the exception you are raising to supply a different traceback message. – trevorKirkby Dec 05 '13 at 02:26
  • @someone-or-other I'm not sure we understand one another - I'm talking about _logging_ the exception's message in addition (or alternatively) to printing it to stdout, not displaying a different one. Though your latter comment makes me think that monkeypatching the `Exception` or `BaseException` class might do the trick... – Tobias Kienzler Dec 05 '13 at 08:28

0 Answers0