Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does one avoid a long stack trace when errors are raised in recursive functions?

Consider the following function:

def fact(x):

    if x == 1:
        return 1

    if x == 2:
        raise Exception("some error")

    return fact(x-1) * x

Calling fact(100) will produce a stack trace with 100 references to the "fact" function. How can one simplify the stack trace to aid debugging? Can something be changed to avoid this big stack?

NB: This is a hypothetical situation which I came up with due to some code I had written a while ago.

like image 810
cammil Avatar asked Jul 28 '26 02:07

cammil


1 Answers

You could try traceback

Here I've written some test code. Tested with Python 3.3.2

import sys
import traceback

def fact(x):
    if x == 0:
        raise Exception("test exception")
    else:
        return fact(x - 1)

def main():
    fact(5)

if __name__ == "__main__":
    try:
        main()
    except:
        (_type, _value, _traceback) = sys.exc_info()
        tb = traceback.extract_tb(_traceback)
        lst = traceback.format_list(tb) 
        lst += [""] # assuming there was no "" in lst
        last_str = None
        last_count = 0
        for s in lst:
            if s == last_str:
                last_count += 1
            else:
                if last_str == None:
                    print(s, end="")
                else:
                    if last_count > 2:
                        print("...omitted %d same items"%(last_count - 2))
                    if last_count > 1:
                        print(last_str, end="")
                    print(s, end="")
                last_str = s
                last_count = 1

Test output:

  File "test.py", line 15, in <module>
    main()
  File "test.py", line 11, in main
    fact(5)
  File "test.py", line 8, in fact
    return fact(x - 1)
...omitted 3 same items
  File "test.py", line 8, in fact
    return fact(x - 1)
  File "test.py", line 6, in fact
    raise Exception("test exception")
like image 177
starrify Avatar answered Jul 29 '26 15:07

starrify