Traceback behaviour in exceptional cases

Here is how i was planning to take care of exceptions in sys.displaytb... 1. When the 'sys' module does not contain a 'stderr' attribute, Python currently prints 'lost sys.stderr' to the original stderr instead of printing the traceback. I propose that it proceed to try to print the traceback to the real stderr in this case. 2. If 'sys.stderr' is buffered, the traceback does not appear in the file. I propose that Python flush 'sys.stderr' immediately after printing a traceback. 3. Tracebacks get printed to whatever object happens to be in 'sys.stderr'. If the object is not a file (or other problems occur during printing), nothing gets printed anywhere. I propose that Python warn about this on stderr, then try to print the traceback to the real stderr as above. 4. Similarly, 'sys.displaytb' may cause an exception. I propose that when this happens, Python invoke its default traceback printer to print the exception from 'sys.displaytb' as well as the original exception. #4 may seem a little convoluted, so here is the exact logic i suggest (described here in Python but to be implemented in C), where 'handle_exception()' is the routine the interpreter uses to handle an exception, 'print_exception' is the built-in exception printer currently implemented in PyErr_PrintEx and PyTraceBack_Print, and 'err' is the actual, original stderr. def print_double_exception(tb, exc, disptb, dispexc, file): file.write("Exception occured during traceback display:\n") print_exception(disptb, dispexc, file) file.write("\n") file.write("Original exception passed to display routine:\n") print_exception(tb, exc, file) def handle_double_exception(tb, exc, disptb, dispexc): if hasattr(sys, 'stderr'): err.write("Missing sys.stderr; printing exception to stderr.\n") print_double_exception(tb, exc, disptb, dispexc, err) return try: print_double_exception(tb, exc, disptb, dispexc, sys.stderr) except: err.write("Error on sys.stderr; printing exception to stderr.\n") print_double_exception(tb, exc, disptb, dispexc, err) def handle_exception(): tb, exc = sys.exc_traceback, sys.exc_value try: sys.displaytb(tb, exc) except: disptb, dispexc = sys.exc_traceback, sys.exc_value try: handle_double_exception(tb, exc, disptb, dispexc) except: pass def default_displaytb(tb, exc): if hasattr(sys, 'stderr'): print_exception(tb, exc, sys.stderr) else: print "Missing sys.stderr; printing exception to stderr." print_exception(tb, exc, err) sys.displaytb = sys.__displaytb__ = default_displaytb -- ?!ng "In the sciences, we are now uniquely privileged to sit side by side with the giants on whose shoulders we stand." -- Gerald Holton
participants (1)
-
Ka-Ping Yee