Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling maximum recursion depth exceeded

I have created a program that uses recursion to solve simple mazes. In the event of a rather complex maze, I get a maximum recursion depth error. I have searched that error on this website and read threads, so I believe I have a general understanding of what is occurring.

Unlike the other threads I saw, I am not trying to increase the recursion limit. sys.setrecursionlimit() is not what I am looking for. I would like to be able handle the overflow, and instead of crashing have the program print a message (print("Sorry but this maze solver was not able to finish analyzing the maze due to recursion limits)) and close.

I am aware of using try and except to handle errors, but I'm not sure if I can incorporate that to handle a maximum recursion depth error.

like image 806
JohnKraz Avatar asked Dec 05 '14 17:12

JohnKraz


1 Answers

A maximum recursion depth error is just another exception; you can catch the RecursionError exception (Python 3.5 or later):

try:
    solveMaze(maze)
except RecursionError as re:
    print('Sorry but this maze solver was not able to finish '
          'analyzing the maze: {}'.format(re.args[0]))

I've incorporated the error message attached to the runtime exception; for a recursion error that's maximum recursion depth exceeded.

If you need to support Python versions earlier than 3.5, you can catch the base class, RuntimeError. If you are worried about catching runtime errors that are not recursion depth errors, you could introspect the .args[0] value:

try:
    solveMaze(maze)
except RuntimeError as re:
    if re.args[0] != 'maximum recursion depth exceeded':
        # different type of runtime error
        raise
    print('Sorry but this maze solver was not able to finish '
          'analyzing the maze: {}'.format(re.args[0]))

Demo of the options:

>>> def infinity(): return infinity()
... 
>>> try:
...     infinity()
... except RecursionError as re:
...     print('Oopsie: {}'.format(re.args[0]))
... 
Oopsie: maximum recursion depth exceeded
>>> def alter_dict_size():
...     dct = {'foo': 'bar'}
...     for key in dct:
...         del dct['foo']
... 
>>> try:
...     alter_dict_size()
... except RuntimeError as re:
...     print('Oopsie: {}'.format(re.args[0]))
... 
Oopsie: dictionary changed size during iteration
>>> try:
...     infinity()
... except RuntimeError as re:
...     if re.args[0] != 'maximum recursion depth exceeded':
...         raise
...     print('Oopsie: {}'.format(re.args[0]))
... 
Oopsie: maximum recursion depth exceeded
>>> try:
...     alter_dict_size()
... except RuntimeError as re:
...     if re.args[0] != 'maximum recursion depth exceeded':
...         raise
...     print('Oopsie: {}'.format(re.args[0]))
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "<stdin>", line 3, in alter_dict_size
RuntimeError: dictionary changed size during iteration

Altering a dictionary size also raises a RuntimeError exception, but testing the resulting exception message allows you to differentiate.

like image 157
Martijn Pieters Avatar answered Nov 02 '22 05:11

Martijn Pieters