45

Is it possible to catch any error in Python? I don't care what the specific exceptions will be, because all of them will have the same fallback.

  • 4
    And like the dog that chases cars down the country road: what will you do when you catch it? Some errors (i.e. MemoryError) mean Python is already crashing. – S.Lott Jul 25 '11 at 14:46
  • @S.Lott Well I've used that in some long running applications to inform me of the problem if possible. Sure some errors will be grave enough that nothing will help (because you can't do anything any longer), but still it's better than nothing. – Voo Jul 25 '11 at 15:13
  • @Voo: "better than nothing"? I find that it's usually worse than noting. Out of Memory, for example, means things have *already* failed to operate properly. Recovery of some valid "prior state" of the Python computation seems impossible. – S.Lott Jul 25 '11 at 18:18
  • 1
    Does this answer your question? [About catching ANY exception](https://stackoverflow.com/questions/4990718/about-catching-any-exception) – Charlie Parker Oct 08 '20 at 15:53
  • maybe this is a better answer? https://stackoverflow.com/a/4992124/1601580 I like this comment in particular `The advantage of except Exception over the bare except is that there are a few exceptions that it wont catch, most obviously KeyboardInterrupt and SystemExit: if you caught and swallowed those then you could make it hard for anyone to exit your script.` – Charlie Parker Jul 22 '22 at 17:54

8 Answers8

60

Using except by itself will catch any exception short of a segfault.

try:
    something()
except:
    fallback()

You might want to handle KeyboardInterrupt separately in case you need to use it to exit your script:

try:
    something()
except KeyboardInterrupt:
    return
except:
    fallback()

There's a nice list of basic exceptions you can catch here. I also quite like the traceback module for retrieving a call stack from the exception. Try traceback.format_exc() or traceback.print_exc() in an exception handler.

lunixbochs
  • 21,757
  • 2
  • 39
  • 47
  • 1
    In most cases, you should also let `NameError` (and perhaps a few others like `AttributeError`) propagate as they inidicate bugs in your code. –  Jul 25 '11 at 14:34
  • 6
    It's often better practice to catch `except Exception` - KeyboardInterrupt and SystemExit don't inherit from Exception, so you can still 'break out'. Depends on what you're doing it for, of course. – Thomas K Jul 25 '11 at 16:32
  • 1
    Where does `fallback()` come from? I receive "NameError: name 'fallback' is not defined"! – Apostolos Aug 21 '20 at 07:48
  • 2
    but I want to pointer to `e` the exception NO MATTER THE TYPE. – Charlie Parker Sep 29 '20 at 15:27
  • @Apostolos answerer. ;) – Charlie Parker Oct 01 '20 at 16:32
  • ... Now I am more confused, @Charlie ... I shouldn't have asked! :)) – Apostolos Oct 01 '20 at 20:48
  • @Apostolos sorry apostolos, you are right, my first comment is confusing. I should have been less careless. Let's fix it now with this comment. My need was that I want to be able to have a pointer to the actual exception. His `except:` doesn't allow that and other answers like `except Exception as e:` don't capture EVERYTHING. The reason I need everything is, if the HPC system I use interputs my script, I want to catch that and then send myself an email about it and then have my script exit safely. – Charlie Parker Oct 01 '20 at 22:35
  • @Charlie, I found this that might be of help: `except: print("Error:", sys.exc_info()[0])` (Re: https://stackoverflow.com/questions/4990718/about-catching-any-exception). I didn't know it myself. So thanks for this exchange! But I just saw that the answer that follows is maybe more close to what you are looking for! – Apostolos Oct 03 '20 at 07:23
  • maybe this is a better answer? https://stackoverflow.com/a/4992124/1601580 I like this comment in particular `The advantage of except Exception over the bare except is that there are a few exceptions that it wont catch, most obviously KeyboardInterrupt and SystemExit: if you caught and swallowed those then you could make it hard for anyone to exit your script.` – Charlie Parker Jul 22 '22 at 17:54
45
try:
    # do something
except Exception, e:
    # handle it

For Python 3.x:

try:
    # do something
except Exception as e:
    # handle it
lukas_o
  • 3,776
  • 4
  • 34
  • 50
Tjekkles
  • 5,352
  • 8
  • 36
  • 53
  • 2
    how is this different from the accepted answer? I see the code is different but do you mind maybe adding some comments/details? – Charlie Parker Feb 07 '17 at 00:05
  • 2
    Exception will not catch all the errors,however except will. – ns15 Mar 29 '17 at 12:16
  • 1
    I dont think this is proper syntax – 3pitt Mar 12 '18 at 20:09
  • 5
    @CharlieParker It's different because in this case you have access to an `Exception` object. – sergzach Aug 23 '19 at 13:16
  • @sergzach so the first option captures ALL errors and gives me a pointer to the exception object through `e`?` – Charlie Parker Sep 29 '20 at 15:27
  • @3pitt did you try it? – Charlie Parker Sep 29 '20 at 15:29
  • @CharlieParker Probably you have another Python version, so, it does not work. Try the second. – sergzach Sep 30 '20 at 06:42
  • maybe this is a better answer? https://stackoverflow.com/a/4992124/1601580 I like this comment in particular `The advantage of except Exception over the bare except is that there are a few exceptions that it wont catch, most obviously KeyboardInterrupt and SystemExit: if you caught and swallowed those then you could make it hard for anyone to exit your script.` – Charlie Parker Jul 22 '22 at 17:54
16

You might want also to look at sys.excepthook:

When an exception is raised and uncaught, the interpreter calls sys.excepthook with three arguments, the exception class, exception instance, and a traceback object. In an interactive session this happens just before control is returned to the prompt; in a Python program this happens just before the program exits. The handling of such top-level exceptions can be customized by assigning another three-argument function to sys.excepthook.

Example:

def except_hook(type, value, tback):
    # manage unhandled exception here
    sys.__excepthook__(type, value, tback) # then call the default handler

sys.excepthook = except_hook
warvariuc
  • 57,116
  • 41
  • 173
  • 227
11

Quoting the bounty text:

I want to be able to capture ANY exception even weird ones like keyboard interrupt or even system exit (e.g. if my HPC manger throws an error) and get a handle to the exception object e, whatever it might be. I want to process e and custom print it or even send it by email

Look at the exception hierarchy, you need to catch BaseException:

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception

This will capture KeyboardInterrupt, SystemExit, and GeneratorExit, which all inherit from BaseException but not from Exception, e.g.

try:
    raise SystemExit
except BaseException as e:
    print("hello world!")
Chris_Rands
  • 38,994
  • 14
  • 83
  • 119
  • In my case, I had to do `print(e.with_traceback(None))`, because `with_traceback` expects one argument. – Matt Oct 25 '22 at 10:06
4

Not mentioning the type of exception you want to handle itself does the job.

Try this:

try:
   #code in which you expect an exception 
except:
   #prints the exception occured

if you want to know the type of exception that occurred:

try:
   # code in which you expect an exception 
except Exception as e:
   print(e)
   # for any exception to be catched
   print(type(e))
   # to know the type of exception.

for detailed explanation go trough this https://www.tutorialspoint.com/python/python_exceptions.htm

Michael M.
  • 10,486
  • 9
  • 18
  • 34
gilf0yle
  • 1,092
  • 3
  • 9
  • 1
    ... and with `print(type(e))` you get also the type of the error (which can be useful too) – Matt Oct 25 '22 at 10:02
3
# in python 3

# if you want the error
try:
    func()
except Exception as e:
    exceptionFunc(e)

# if you simply want to know an error occurs
try:
    func()
except:
    exceptionFunc()

# if you don't even wanna do anything
try:
    func()
except:
    pass
kennysliding
  • 2,783
  • 1
  • 10
  • 31
1

The following only worked for me (both in PY2 and PY3):

try:
  # (Anything that produces any kind of error)
except:
  ertype = sys.exc_info()[0]  # E.g. <class 'PermissionError'>
  description = sys.exc_info()[1]   # E.g. [Errno 13] Permission denied: ...
  # (Handle as needed ) 
Apostolos
  • 3,115
  • 25
  • 28
0

Built-In Exceptions in Python

Built-In exception classes are divided into Base error classes from which the error classes are defined and Concrete error classes which define exceptions which you are more likely to see time to time.

The more detailed document about the buit-In exception can be found in [https://docs.python.org/3/library/exceptions.html]

Custom Exceptions

It is used to fit your specific application situation. For example, you can create your own exception as RecipeNotValidError as the recipe is not valid in your class for developing a cooking app.

Implementation


class RecipeNotValidError(Exception):    
    def __init__(self):       
        self.message = "Your recipe is not valid"        
        try:            
            raise RecipeNotValidError
        except RecipeNotValidError as e:            
            print(e.message)

These are custom exceptions that are not defined in the standard library. The steps you can follow to create custom classes are :

  1. Subclass the Exception class.
  2. Create a new Exception class of your choice.
  3. Write your code and use the try...except flow to capture and handle your custom exception.
DKT
  • 41
  • 5
  • Yes, but the question here was "how to catch any exception and get its error object?" It was about handling even unexpected errors. – Matt Oct 25 '22 at 09:58