How to limit python traceback to specific files

In order to print your own stacktrace, you would need to handle all unhandled exceptions yourself; this is how the sys.excepthook becomes handy.

The signature for this function is sys.excepthook(type, value, traceback) and its job is:

This function prints out a given traceback and exception to sys.stderr.

So as long as you can play with the traceback and only extract the portion you care about you should be fine. Testing frameworks do that very frequently; they have custom assert functions which usually does not appear in the traceback, in other words they skip the frames that belong to the test framework. Also, in those cases, the tests usually are started by the test framework as well.

You end up with a traceback that looks like this:

[ custom assert code ] + ... [ code under test ] ... + [ test runner code ]

How to identify your code.

You can add a global to your code:

__mycode = True

Then to identify the frames:

def is_mycode(tb):
  globals = tb.tb_frame.f_globals
  return globals.has_key('__mycode')

How to extract your frames.

  1. skip the frames that don’t matter to you (e.g. custom assert code)
  2. identify how many frames are part of your code -> length
  3. extract length frames

    def mycode_traceback_levels(tb):
      length = 0
      while tb and is_mycode(tb):
        tb = tb.tb_next
        length += 1
      return length
    

Example handler.

def handle_exception(type, value, tb):
  # 1. skip custom assert code, e.g.
  # while tb and is_custom_assert_code(tb):
  #   tb = tb.tb_next
  # 2. only display your code
  length = mycode_traceback_levels(tb)
  print ''.join(traceback.format_exception(type, value, tb, length))

install the handler:

sys.excepthook = handle_exception

What next?

You could adjust length to add one or more levels if you still want some info about where the failure is outside of your own code.

see also https://gist.github.com/dnozay/b599a96dc2d8c69b84c6

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)