Univention Bugzilla – Bug 32979
reraise of exceptions
Last modified: 2015-01-08 13:59:32 CET
Currently we are reraising many exceptions in the UMC UDM module backend. This has the disadvantage that the original stacktrace gets lost. We should adapt at least the "raise e" → "raise". It would be useful to log tracebacks if we change the exception. I think i oneday saw a python syntax to raise a tuple of *sys.exc_info. So maybe it is possible to cast the exception without getting lost of the traceback. e.g.: exc = sys.exc_info() raise UMC_ConnectionError, exc[1], exc[2] udm/udm_ldap.py: 148: raise e 160: raise e 168: raise e 180: raise e 182: raise LDAP_ConnectionError( str( e ) ) 311: raise UMC_CommandError( str( e ) ) 316: raise UMC_CommandError( str( e ) ) 353: raise UDM_Error( get_exception_msg(e), obj.dn ) 372: raise UDM_Error( get_exception_msg( e ) ) 387: raise UDM_Error( get_exception_msg( e ) ) 413: raise UDM_Error( get_exception_msg(e) ) 448: raise e 450: raise UDM_Error( get_exception_msg( e ) ) 472: raise e 475: raise UDM_Error( get_exception_msg( e ) ) 841: raise e 854: raise e 982: raise e 984: raise UDM_Error( get_exception_msg( e ) )
<http://stackoverflow.com/questions/4825234/exception-traceback-is-hidden-if-not-re-raised-immediately> <http://docs.python.org/2/reference/simple_stmts.html#grammar-token-raise_stmt> #!/usr/bin/python import sys import traceback def foo(): raise KeyError("foo") def bar(): try: foo() except KeyError as ex: print "bar.type=%s" % (type(ex),) print "bar.ex=%s" % (ex,) info = sys.exc_info() msg = "foo() failed in context 'bar': %s" % (info[1],) raise IndexError, msg, info[2] def main(): try: bar() except (KeyError, LookupError) as ex: print "main.type=%s" % (type(ex),) print "main.ex=%s" % (ex,) traceback.print_exc() if __name__ == "__main__": main() bar.type=<type 'exceptions.KeyError'> bar.ex='foo' main.type=<type 'exceptions.IndexError'> main.ex=foo() failed in context 'bar': 'foo' Traceback (most recent call last): File "/tmp/exception.py", line 20, in main bar() File "/tmp/exception.py", line 10, in bar foo() File "/tmp/exception.py", line 6, in foo raise KeyError("foo") IndexError: foo() failed in context 'bar': 'foo'
This is especially a problem with the LDAP_Connection decorator (which is used everywhere) as it can mask important traceback information.
Created attachment 5812 [details] cleanup LDAP_Connection decorator
Bug#34436 is an example of a traceback which does not really provide enough information. This Bug should be fixed.
Again received a feedback where the exception is reraised without the traceback.
We received again a traceback which doesn't offer any relevant information.
The two biggest problems were the LDAP_ConnectionError exception and if a function which already uses @LDAP_Connection calls another function which uses the decorator, too. * The LDAP_ConnectionError was removed as it hides every exception detail which is required to reproduce a problem when the initialization of the module fails. * No exception is reraised with 'raise e' anymore. * Even UDM_Error exceptions which result in a "user friendly" error message preserve the original traceback of the last raised exception. * A error_handling() function has been implemented to separate error handling from LDAP actions * If an LDAP error (not UDM error) occurs the current opened LDAP connection is thrown away. On the next LDAP action a new one is created. * Tracebacks are now generated in the same way as in the UMC core (1*) * Logging of exceptions has been improved Fix: svn r56420, svn r56478 Package: univention-management-console-module-udm (5.1.25-5) YAML: 2014-11-25-univention-management-console-module-udm.yaml *1) msg1 = before, msg2 = after >>> msg1 = '%s\n%s: %s\n' % (''.join(traceback.format_tb(thread.exc_info[2])), thread.exc_info[0].__name__, str(thread.exc_info[1])) >>> msg2 = ''.join(traceback.format_exception(*thread.exc_info)) >>> >>> msg1 ' File "<stdin>", line 2, in <module>\n\nNameError: name \'asdf\' is not defined\n' >>> msg2 'Traceback (most recent call last):\n File "<stdin>", line 2, in <module>\nNameError: name \'asdf\' is not defined\n'
Works. Much better.
http://errata.univention.de/ucs/4.0/18.html