On Dec 14, 11:00 pm, ab <andrewb...@gmail.com> wrote:
> > `wrap_and_raise()` will appear in the traceback, `raise  
> > wrap_exception(SomeException())` would be cleaner.
>
> I like that

But you must use the three-argument `raise` statement to supply your
own traceback in Python 2.x. You could dispense with the function
entirely if you're happy to repeat `import sys; raise NewException(),
None, sys.exc_info()[2]` instead--although then you lose some
information, see below.


> > Your patch seems to swallow the new exception's traceback now instead
> > of the causing traceback. That might be good in some situations, but
> > generally both should be preserved.

No; the only part of the traceback lost is the `raise` line within
`wrap_and_raise`; the remainder of the traceback which would
correspond to all but the `raise` line of the new exception's
traceback is preserved. But if you weren't using the `wrap_and_raise`
function, you would lose the line of the traceback where the new
exception was raised. Put the following code in a python script and
compare the tracebacks when it calls wrapped(), unwrapped(), or
manually_wrapped():


def wrap_and_raise(new_exception):
  import sys
  exc_class, exc, tb = sys.exc_info()
  if issubclass(exc_class, Exception):
    raise new_exception, None, tb
  else:
    raise new_exception

def valueerror():
  raise ValueError("This is a ValueError")

def wrapped():
  try:
    valueerror()
  except:
    wrap_and_raise(StandardError("This error normally hides the
original error"))

def unwrapped():
  try:
    valueerror()
  except:
    raise StandardError("This error hides the original error")

def manually_wrapped():
  import sys
  try:
    valueerror()
  except:
    raise StandardError("This error normally hides the original
error"), None, sys.exc_info()[2]

# Try each of these
wrapped()
# unwrapped()
# manually_wrapped()



> > Better yet, make all exceptions that are used to reraise other  
> > exceptions a subclass of WrappingException (pick a better name) that  
> > either takes a `cause=exc` or `wrap=True` kwarg. This way, you don't  
> > have to add imports everywhere.
>
> I don't like that. An invalid template exception might be "wrapping"
> sometimes, but not others.

TemplateSyntaxError is an obvious example. Also, if you do this you're
still not preserving the original traceback.


> Another question: how should the tests for this ticket be written?

I'm not sure (which is why I didn't write any tests originally).
Obviously you'd raise an exception, catch it, and wrap_and_raise
another. I suppose you could examine the output of
`traceback.format_exc()` or one of its other functions to see if the
original exception is now mentioned in the traceback.

Andrew.

--

You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.


Reply via email to