âčïž Skipped - page is already crawled
| Filter | Status | Condition | Details |
|---|---|---|---|
| HTTP status | PASS | download_http_code = 200 | HTTP 200 |
| Age cutoff | PASS | download_stamp > now() - 6 MONTH | 0 months ago |
| History drop | PASS | isNull(history_drop_reason) | No drop reason |
| Spam/ban | PASS | fh_dont_index != 1 AND ml_spam_score = 0 | ml_spam_score=0 |
| Canonical | PASS | meta_canonical IS NULL OR = '' OR = src_unparsed | Not set |
| Property | Value |
|---|---|
| URL | https://realpython.com/python-exceptions/ |
| Last Crawled | 2026-04-16 08:18:11 (23 hours ago) |
| First Indexed | 2018-04-30 15:15:56 (7 years ago) |
| HTTP Status Code | 200 |
| Meta Title | Python Exceptions: An Introduction â Real Python |
| Meta Description | In this beginner tutorial, you'll learn what exceptions are good for in Python. You'll see how to raise exceptions and how to handle them with try ... except blocks. |
| Meta Canonical | null |
| Boilerpipe Text | by
Said van de Klundert
Reading time estimate
24m
basics
python
Python exceptions provide a mechanism for handling errors that occur during the execution of a program. Unlike syntax errors, which are detected by the parser, Python raises exceptions when an error occurs in syntactically correct code. Knowing how to raise, catch, and handle exceptions effectively helps to ensure your program behaves as expected, even when encountering errors.
By the end of this tutorial, youâll understand that:
Exceptions in Python occur when
syntactically correct code
results in an
error
.
The
try
âŠ
except
block
lets you execute code and handle exceptions that arise.
You can use the
else
, and
finally
keywords
for more refined
exception handling
.
Itâs
bad practice
to
catch all exceptions
at once using
except Exception
or the bare
except
clause.
Combining
try
,
except
, and
pass
allows your program to
continue silently
without handling the exception.
In this tutorial, youâll get to know Python exceptions and all relevant keywords for exception handling by walking through a practical example of handling a platform-related exception. Finally, youâll also learn how to create your own custom Python exceptions.
Take the Quiz:
Test your knowledge with our interactive âPython Exceptions: An Introductionâ quiz. Youâll receive a score upon completion to help you track your learning progress:
Interactive Quiz
Python Exceptions: An Introduction
In this quiz, you'll test your understanding of Python exceptions. You'll cover the difference between syntax errors and exceptions and learn how to raise exceptions, make assertions, and use the try and except block.
Understanding Exceptions and Syntax Errors
Syntax errors
occur when the parser detects an incorrect statement. Observe the following example:
The arrow indicates where the parser ran into the
syntax error
. Additionally, the error message gives you a hint about what went wrong. In this example, there was one bracket too many. Remove it and run your code again:
This time, you ran into an
exception error
. This type of error occurs whenever syntactically correct Python code results in an error. The last line of the message indicates what type of exception error you ran into.
Instead of just writing
exception error
, Python details what
type
of exception error it encountered. In this case, it was a
ZeroDivisionError
. Python comes with
various built-in exceptions
as well as the possibility to create user-defined exceptions.
Raising an Exception in Python
There are scenarios where you might want to stop your program by raising an exception if a condition occurs. You can do this with the
raise
keyword:
You can even complement the statement with a custom message. Assume that youâre writing a tiny toy program that expects only numbers up to
5
. You can raise an error when an unwanted condition occurs:
In this example, you raised an
Exception
object and passed it an informative custom message. You built the message using an
f-string
and a
self-documenting expression
.
When you run
low.py
, youâll get the following output:
The program comes to a halt and displays the exception to your
terminal
or
REPL
, offering you helpful clues about what went wrong. Note that the final call to
print()
never executed, because Python raised the exception before it got to that line of code.
With the
raise
keyword, you can raise any exception object in Python and stop your program when an unwanted condition occurs.
Debugging During Development With
assert
Before moving on to the most common way of working with exceptions in Python using
the
try
âŠ
except
block
, youâll take a quick look at an exception thatâs a bit different than the others.
Python offers a specific exception type that you should only use when debugging your program during development. This exception is the
AssertionError
. The
AssertionError
is special because you shouldnât ever raise it yourself using
raise
.
Instead, you use
the
assert
keyword
to check whether a condition is met and let Python raise the
AssertionError
if the condition isnât met.
The idea of an assertion is that your program should only attempt to run if certain conditions are in place. If Python checks your assertion and finds that the condition is
True
, then that is excellent! The program can continue. If the condition turns out to be
False
, then your program raises an
AssertionError
exception and stops right away:
Revisit your tiny script,
low.py
, from
the previous section
. Currently, youâre explicitly raising an exception when a certain condition isnât met:
Assuming that youâll handle this constraint safely for your production system, you could replace this
conditional statement
with an assertion for a quick way to retain this sanity check during development:
If the
number
in your program is below
5
, then the assertion passes and your script continues with the next line of code. However, if you set
number
to a value higher than
5
âfor example,
10
âthen the outcome of the assertion will be
False
:
In that case, Python raises an
AssertionError
that includes the message you passed, and ends the program execution:
In this example, raising an
AssertionError
exception is the last thing that the program will do. The program will then come to halt and wonât continue. The call to
print()
that follows the assertion wonât execute.
Using assertions in this way can be helpful when youâre debugging your program during development because it can be quite a fast and straightforward to add assertions into your code.
However, you shouldnât rely on assertions for catching crucial run conditions of your program in production. Thatâs because Python globally disables assertions when you run it in optimized mode using the
-O
and
-OO
command line options
:
In this run of your program, you used the
-O
command line option, which removes all
assert
statements. Therefore, your script ran all the way to the end and displayed a number that is
dreadfully
high!
In production, your Python code may run using this optimized mode, which means that assertions arenât a reliable way to handle runtime errors in production code. They can be quick and useful helpers when your debugging your code, but you should never use assertions to set crucial constraints for your program.
If
low.py
should reliably fail when
number
is above
5
, then itâs best to stick with
raising an exception
. However, sometimes you might not want your program to fail when it encounters an exception, so how should you handle those situations?
Handling Exceptions With the
try
and
except
Block
In Python, you use the
try
and
except
block to catch and handle exceptions. Python executes code following the
try
statement as a normal part of the program. The code that follows the
except
statement is the programâs response to any exceptions in the preceding
try
clause:
As you saw earlier, when syntactically correct code runs into an error, Python will raise an exception error. This exception error will crash the program if you donât handle it. In the
except
clause, you can determine how your program should respond to exceptions.
The following function can help you understand the
try
and
except
block:
The
linux_interaction()
can only run on a Linux system. Python will raise a
RuntimeError
exception if you call it on an operating system other then Linux.
You can give the function a
try
by adding the following code:
The way you handled the error here is by handing out a
pass
. If you run this code on a macOS or Windows machine, then you get the following output:
You got nothing in response. The good thing here is that your program didnât crash. But letting an exception that occurred pass silently is bad practice. You should always at least know about and
log
if some type of exception occurred when you ran your code.
To this end, you can change
pass
into something that generates an informative message:
When you now execute this code on a macOS or Windows machine, youâll see the message from your
except
block printed to the console:
When an exception occurs in a program that runs this function, then the program will continue as well as inform you about the fact that the function call wasnât successful.
What you didnât get to see was the type of error that Python raised as a result of the function call. In order to see exactly what went wrong, youâd need to catch the error that the function raised.
The following code is an example where you capture the
RuntimeError
and output that message to your screen:
In the
except
clause, you assign the
RuntimeError
to the temporary variable
error
âoften also called
err
âso that you can access the exception object in the indented block. In this case, youâre printing the objectâs string representation, which corresponds to the error message attached to the object.
Running this function on a macOS or Windows machine outputs the following:
The first message is the
RuntimeError
, informing you that Python can only execute the function on a Linux machine. The second message tells you which function wasnât executed.
In the example above, you called a function that you wrote yourself. When you executed the function, you caught the
RuntimeError
exception and printed it to your screen.
Hereâs another example where you open a file and use a built-in exception:
If
file.log
doesnât exist, then this block of code will output the following:
This is an informative message, and your program will still continue to run. However, your
except
block will currently catch
any
exception, whether thatâs related to not being able to open the file or not. You could lead yourself onto a confusing path if you see this message even when Python raises a completely unrelated exception.
Therefore, itâs always best to be
specific
when youâre handling an exception.
In the
Python docs
, you can see that there are a couple of built-in exceptions that you could raise in such a situation, for example:
exception
FileNotFoundError
Raised when a file or directory is requested but doesnât exist. Corresponds to errno ENOENT. (
Source
)
You want to handle the situation when Python canât find the requested file. To catch this type of exception and print it to screen, you could use the following code:
In this case, if
file.log
doesnât exist, then the output will be the following:
You can have more than one function call in your
try
clause and anticipate catching various exceptions. Something to note here is that the code in the
try
clause will stop as soon as it encounters any one exception.
Look at the following code. Here, you first call
linux_interaction()
and then try to open a file:
If you run this code on a macOS or Windows machine, then youâll see the following:
Inside the
try
clause, you ran into an exception immediately and didnât get to the part where you attempt to open
file.log
. Now look at what happens when you run the code on a Linux machine if the file doesnât exist:
Note that if youâre handling specific exceptions as you did above, then the order of the
except
clauses doesnât matter too much. Itâs all about which of the exceptions Python raises first. As soon as Python raises an exception, it checks the except clauses from top to bottom and executes the first matching one that it finds.
Here are the key takeaways about using Pythonâs
try
âŠ
except
statements:
Python executes a
try
clause up until the point where it encounters the first exception.
Inside the
except
clauseâthe exception handlerâyou determine how the program responds to the exception.
You can anticipate
multiple exceptions
and differentiate how the program should respond to them.
Avoid using bare
except
clauses
, because they can hide unexpected exceptions.
While using
try
together with
except
is probably the most common error handling that youâll encounter, thereâs more that you can do to fine-tune your programâs response to exceptions.
Proceeding After a Successful Try With
else
You can use Pythonâs
else
statement to instruct a program to execute a certain block of code only in the absence of exceptions:
Look at the following example:
If you were to run this code on a Linux system, then the output would be the following:
Because the program didnât run into
any
exceptions, Python executed the code in the
else
clause. However, if you run this code on a macOS or Windows system, then you get a different output:
The
linux_interaction()
function raised a
RuntimeError
. Youâve handled the exception, so your program doesnât crash, and instead prints the exception message to the console. The code nested under the
else
clause, however, doesnât execute, because Python encountered an exception during execution.
Note that structuring your code like this is different from just adding the call to
print()
outside of the context of the
try
âŠ
except
block:
If you donât nest the
print()
call under the
else
clause, then itâll execute even if Python encounters the
RuntimeError
that you handle in the
except
block above. On a Linux system, the output would be the same, but on macOS or Windows, youâd get the following output:
Nesting code under the
else
clause assures that itâll only run when Python doesnât encounter any exception when executing the
try
âŠ
except
block.
You can also create a nested
try
âŠ
except
block inside the
else
clause and catch possible exceptions there as well:
If you were to execute this code on a Linux machine, then youâd get the following result:
From the output, you can see that
linux_interaction()
ran. Because Python encountered no exceptions, it attempted to open
file.log
. That file didnât exist, but instead of letting the program crash, you caught the
FileNotFoundError
exception and printed a message to the console.
Cleaning Up After Execution With
finally
Imagine that you always had to implement some sort of action to clean up after executing your code. Python enables you to do so using the
finally
clause:
Have a look at the following example:
In this code, Python will execute everything in the
finally
clause. It doesnât matter if you encounter an exception somewhere in any of the
try
âŠ
except
blocks. Running the code on a macOS or Windows machine will output the following:
Note that the code inside the
finally
block will execute regardless of whether or not youâre handling the exceptions:
You simplified the example code from above, but
linux_interaction()
still raises an exception on a macOS or Windows system. If you now run this code on an operating system other than Linux, then youâll get the following output:
Despite the fact that Python raised the
RuntimeError
, the code in the
finally
clause still executed and printed the message to your console.
This can be helpful because even code outside of a
try
âŠ
except
block wonât necessarily execute if your script encounters an unhandled exception. In that case, your program will terminate and the code
after
the
try
âŠ
except
block will never run. However, Python will still execute the code inside of the
finally
clause. This helps you make sure that resources like
file handles
and
database connections
are cleaned up properly.
Creating Custom Exceptions in Python
With the large number of built-in exceptions that Python offers, youâll likely find a fitting type when deciding which exception to raise. However, sometimes your code wonât fit the mold.
Python makes it straightforward to create custom exception types by inheriting from a built-in exception. Think back to your
linux_interaction()
function:
Using a
RuntimeError
isnât a bad choice in this situation, but it would be nice if your exception name was a bit more specific. For this, you can create a custom exception:
You generally create a custom exception in Python by inheriting from
Exception
, which is the base class for most built-in Python exceptions as well. You could also inherit from a different exception, but choosing
Exception
is usually the best choice.
Thatâs really all that you need to do. In the code snippet above, you also added a
docstring
that describes the exception type and serves as the class body.
While you can customize your exception object, you donât need to do that. Itâs often enough to give your custom Python exceptions a descriptive name, so youâll know what happened when Python raises this exception in your code.
Now that youâve defined the custom exception, you can raise it like any other Python exception:
If you now call
linux_interaction()
on macOS or Windows, then youâll see that Python raises your custom exception:
You could even use your custom
PlatformException
as a parent class for other custom exceptions that you could descriptively name for each of the platforms that users may run your code on.
Conclusion
At this point, youâre familiar with the basics of using Python exceptions. After seeing the difference between syntax errors and exceptions, you learned about various ways to raise, catch, and handle exceptions in Python. You also learned how you can create your own custom exceptions.
In this article, you gained experience working with the following exception-related keywords:
raise
allows you to raise an exception at any time.
assert
enables you to verify if a certain condition is met and raises an exception if it isnât.
In the
try
clause, all statements are executed until an exception is encountered.
except
allows you to catch and handle the exception or exceptions that Python encountered in the
try
clause.
else
lets you code sections that should run only when Python encounters no exceptions in the
try
clause.
finally
enables you to execute sections of code that should always run, whether or not Python encountered any exceptions.
You now understand the basic tools that Python offers for dealing with exceptions. If youâre curious about the topic and want to dive deeper, then take a look at the following tutorials:
Pythonâs Built-in Exceptions: A Walkthrough With Examples
Exception Groups and
except*
Python
raise
: Effectively Raising Exceptions in Your Code
How to Catch Multiple Exception in Python
Understanding the Python Traceback
LBYL vs EAFP: Preventing or Handling Errors in Python
Whatâs your favorite aspect of exception handling in Python? Share your thoughts in the comments below.
Frequently Asked Questions
Now that you have some experience with Python exceptions, you can use the questions and answers below to check your understanding and recap what youâve learned.
These FAQs are related to the most important concepts youâve covered in this tutorial. Click the
Show/Hide
toggle beside each question to reveal the answer.
Exceptions in Python are errors that occur during the execution of a program, disrupting the normal flow of the program.
You handle exceptions in Python using a
try
âŠ
except
block. Python executes the code in the
try
block and if an exception occurs, it switches to executing the code in the
except
block to handle the exception. However, only the exceptions that are explicitly specified in the
except
block will be handled. If an exception is not caught, itâll propagate up the call stack and may result in the termination of your program.
To catch all exceptions in Python, you can use a bare
except
clause or write
except Exception
, but itâs recommended to catch specific exceptions to avoid masking unexpected errors.
In a
try
âŠ
except
block, Python executes the code under
try
and if an exception occurs, it immediately jumps to the
except
block to handle it, allowing the program to continue running.
Using
try
âŠ
except
with
pass
allows the program to ignore the exception and continue execution without taking any specific action in response to the error. However, this practice can hide potential issues, making it harder to debug and maintain the code, so use it with caution. Itâs generally better to either handle the exception explicitly or log it for debugging purposes.
You raise an exception in Python using the
raise
keyword followed by an exception object, which can include a custom message.
You can use the
assert
keyword to check if a condition is true during development. If the condition is false, it raises an
AssertionError
, which can help with debugging. Note that assertions can be disabled by running Python with the
-O
(optimize) flag. Therefore, you shouldnât rely on assertions for critical checks in production code, as they may be ignored.
The
finally
clause contains code that will always execute after a
try
block, regardless of whether an exception was raised or not, ensuring necessary cleanup actions occur.
Take the Quiz:
Test your knowledge with our interactive âPython Exceptions: An Introductionâ quiz. Youâll receive a score upon completion to help you track your learning progress:
Interactive Quiz
Python Exceptions: An Introduction
In this quiz, you'll test your understanding of Python exceptions. You'll cover the difference between syntax errors and exceptions and learn how to raise exceptions, make assertions, and use the try and except block. |
| Markdown | [](https://realpython.com/)
- [Start Here](https://realpython.com/start-here/)
- [Learn Python](https://realpython.com/python-exceptions/)
[Python Tutorials â In-depth articles and video courses](https://realpython.com/search?kind=article&kind=course&order=newest)
[Learning Paths â Guided study plans for accelerated learning](https://realpython.com/learning-paths/)
[Quizzes & Exercises â Check your learning progress](https://realpython.com/quizzes/)
[Browse Topics â Focus on a specific area or skill level](https://realpython.com/tutorials/all/)
[Community Chat â Learn with other Pythonistas](https://realpython.com/community/)
[Office Hours â Live Q\&A calls with Python experts](https://realpython.com/office-hours/)
[Live Courses â Live, instructor-led Python courses](https://realpython.com/live/)
[Podcast â Hear whatâs new in the world of Python](https://realpython.com/podcasts/rpp/)
[Books â Round out your knowledge and learn offline](https://realpython.com/products/books/)
[Reference â Concise definitions for common Python terms](https://realpython.com/ref/)
[Code Mentor âBeta Personalized code assistance & learning tools](https://realpython.com/mentor/)
[Unlock All Content â](https://realpython.com/account/join/)
- [More](https://realpython.com/python-exceptions/)
[Learner Stories](https://realpython.com/learner-stories/) [Python Newsletter](https://realpython.com/newsletter/) [Python Job Board](https://www.pythonjobshq.com/) [Meet the Team](https://realpython.com/team/) [Become a Contributor](https://realpython.com/jobs/)
- [Search](https://realpython.com/search "Search")
- [Join](https://realpython.com/account/join/)
- [SignâIn](https://realpython.com/account/login/?next=%2Fpython-exceptions%2F)
[Browse Topics](https://realpython.com/tutorials/all/)
[Guided Learning Paths](https://realpython.com/learning-paths/)
[Basics](https://realpython.com/search?level=basics)
[Intermediate](https://realpython.com/search?level=intermediate)
[Advanced](https://realpython.com/search?level=advanced)
***
[ai](https://realpython.com/tutorials/ai/) [algorithms](https://realpython.com/tutorials/algorithms/) [api](https://realpython.com/tutorials/api/) [best-practices](https://realpython.com/tutorials/best-practices/) [career](https://realpython.com/tutorials/career/) [community](https://realpython.com/tutorials/community/) [databases](https://realpython.com/tutorials/databases/) [data-science](https://realpython.com/tutorials/data-science/) [data-structures](https://realpython.com/tutorials/data-structures/) [data-viz](https://realpython.com/tutorials/data-viz/) [devops](https://realpython.com/tutorials/devops/) [django](https://realpython.com/tutorials/django/) [docker](https://realpython.com/tutorials/docker/) [editors](https://realpython.com/tutorials/editors/) [flask](https://realpython.com/tutorials/flask/) [front-end](https://realpython.com/tutorials/front-end/) [gamedev](https://realpython.com/tutorials/gamedev/) [gui](https://realpython.com/tutorials/gui/) [machine-learning](https://realpython.com/tutorials/machine-learning/) [news](https://realpython.com/tutorials/news/) [numpy](https://realpython.com/tutorials/numpy/) [projects](https://realpython.com/tutorials/projects/) [python](https://realpython.com/tutorials/python/) [stdlib](https://realpython.com/tutorials/stdlib/) [testing](https://realpython.com/tutorials/testing/) [tools](https://realpython.com/tutorials/tools/) [web-dev](https://realpython.com/tutorials/web-dev/) [web-scraping](https://realpython.com/tutorials/web-scraping/)
[Table of Contents](https://realpython.com/python-exceptions/#toc)
- [Understanding Exceptions and Syntax Errors](https://realpython.com/python-exceptions/#understanding-exceptions-and-syntax-errors)
- [Raising an Exception in Python](https://realpython.com/python-exceptions/#raising-an-exception-in-python)
- [Debugging During Development With assert](https://realpython.com/python-exceptions/#debugging-during-development-with-assert)
- [Handling Exceptions With the try and except Block](https://realpython.com/python-exceptions/#handling-exceptions-with-the-try-and-except-block)
- [Proceeding After a Successful Try With else](https://realpython.com/python-exceptions/#proceeding-after-a-successful-try-with-else)
- [Cleaning Up After Execution With finally](https://realpython.com/python-exceptions/#cleaning-up-after-execution-with-finally)
- [Creating Custom Exceptions in Python](https://realpython.com/python-exceptions/#creating-custom-exceptions-in-python)
- [Conclusion](https://realpython.com/python-exceptions/#conclusion)
- [Frequently Asked Questions](https://realpython.com/python-exceptions/#frequently-asked-questions)
Mark as Completed
Share
Recommended Courses
[ Raising and Handling Python Exceptions 1h 2m · 13 lessons](https://realpython.com/courses/raising-handling-exceptions/)
View 1 more course
- [Introduction to Python Exceptions](https://realpython.com/courses/introduction-python-exceptions/) 13m · 3 lessons

# Python Exceptions: An Introduction
by [Said van de Klundert](https://realpython.com/python-exceptions/#author)
Reading time estimate
24m
[35 Comments](https://realpython.com/python-exceptions/#reader-comments)
[basics](https://realpython.com/tutorials/basics/) [python](https://realpython.com/tutorials/python/)
Mark as Completed
Share
Table of Contents
- [Understanding Exceptions and Syntax Errors](https://realpython.com/python-exceptions/#understanding-exceptions-and-syntax-errors)
- [Raising an Exception in Python](https://realpython.com/python-exceptions/#raising-an-exception-in-python)
- [Debugging During Development With assert](https://realpython.com/python-exceptions/#debugging-during-development-with-assert)
- [Handling Exceptions With the try and except Block](https://realpython.com/python-exceptions/#handling-exceptions-with-the-try-and-except-block)
- [Proceeding After a Successful Try With else](https://realpython.com/python-exceptions/#proceeding-after-a-successful-try-with-else)
- [Cleaning Up After Execution With finally](https://realpython.com/python-exceptions/#cleaning-up-after-execution-with-finally)
- [Creating Custom Exceptions in Python](https://realpython.com/python-exceptions/#creating-custom-exceptions-in-python)
- [Conclusion](https://realpython.com/python-exceptions/#conclusion)
- [Frequently Asked Questions](https://realpython.com/python-exceptions/#frequently-asked-questions)
[Remove ads](https://realpython.com/account/join/)
Recommended Courses
[Raising and Handling Python Exceptions](https://realpython.com/courses/raising-handling-exceptions/) (1h 2m)
1 more course
- [Introduction to Python Exceptions](https://realpython.com/courses/introduction-python-exceptions/) (13m)
Python exceptions provide a mechanism for handling errors that occur during the execution of a program. Unlike syntax errors, which are detected by the parser, Python raises exceptions when an error occurs in syntactically correct code. Knowing how to raise, catch, and handle exceptions effectively helps to ensure your program behaves as expected, even when encountering errors.
**By the end of this tutorial, youâll understand that:**
- Exceptions in Python occur when **syntactically correct code** results in an **error**.
- **The `try` ⊠`except` block** lets you execute code and handle exceptions that arise.
- You can use the `else`, and `finally` **keywords** for more refined **exception handling**.
- Itâs **bad practice** to **catch all exceptions** at once using `except Exception` or the bare `except` clause.
- Combining `try`, `except`, and `pass` allows your program to **continue silently** without handling the exception.
In this tutorial, youâll get to know Python exceptions and all relevant keywords for exception handling by walking through a practical example of handling a platform-related exception. Finally, youâll also learn how to create your own custom Python exceptions.
**Get Your Code:** [Click here to download the free sample code](https://realpython.com/bonus/python-exceptions-code/) that shows you how exceptions work in Python.
***Take the Quiz:*** Test your knowledge with our interactive âPython Exceptions: An Introductionâ quiz. Youâll receive a score upon completion to help you track your learning progress:
***
[](https://realpython.com/quizzes/python-exceptions/)
**Interactive Quiz**
[Python Exceptions: An Introduction](https://realpython.com/quizzes/python-exceptions/)
In this quiz, you'll test your understanding of Python exceptions. You'll cover the difference between syntax errors and exceptions and learn how to raise exceptions, make assertions, and use the try and except block.
## Understanding Exceptions and Syntax Errors
[Syntax errors](https://realpython.com/invalid-syntax-python/) occur when the parser detects an incorrect statement. Observe the following example:
Python Traceback
```
```
The arrow indicates where the parser ran into the **syntax error**. Additionally, the error message gives you a hint about what went wrong. In this example, there was one bracket too many. Remove it and run your code again:
Python
```
```
This time, you ran into an **exception error**. This type of error occurs whenever syntactically correct Python code results in an error. The last line of the message indicates what type of exception error you ran into.
Instead of just writing *exception error*, Python details what *type* of exception error it encountered. In this case, it was a `ZeroDivisionError`. Python comes with [various built-in exceptions](https://docs.python.org/3/library/exceptions.html) as well as the possibility to create user-defined exceptions.
[Remove ads](https://realpython.com/account/join/)
## Raising an Exception in Python
There are scenarios where you might want to stop your program by raising an exception if a condition occurs. You can do this with the [`raise`](https://realpython.com/python-raise-exception/) keyword:
[](https://files.realpython.com/media/raise.3931e8819e08.png)
You can even complement the statement with a custom message. Assume that youâre writing a tiny toy program that expects only numbers up to `5`. You can raise an error when an unwanted condition occurs:
Python `low.py`
```
```
In this example, you raised an `Exception` object and passed it an informative custom message. You built the message using an [f-string](https://realpython.com/python-f-strings/) and a [self-documenting expression](https://realpython.com/python-f-strings/#self-documenting-expressions-for-debugging).
When you run `low.py`, youâll get the following output:
Python Traceback
```
```
The program comes to a halt and displays the exception to your [terminal](https://realpython.com/terminal-commands/) or [REPL](https://realpython.com/python-repl/), offering you helpful clues about what went wrong. Note that the final call to [`print()`](https://realpython.com/python-print/) never executed, because Python raised the exception before it got to that line of code.
With the `raise` keyword, you can raise any exception object in Python and stop your program when an unwanted condition occurs.
## Debugging During Development With `assert`
Before moving on to the most common way of working with exceptions in Python using [the `try` ⊠`except` block](https://realpython.com/python-exceptions/#handling-exceptions-with-the-try-and-except-block), youâll take a quick look at an exception thatâs a bit different than the others.
Python offers a specific exception type that you should only use when debugging your program during development. This exception is the `AssertionError`. The `AssertionError` is special because you shouldnât ever raise it yourself using `raise`.
Instead, you use [the `assert` keyword](https://dbader.org/blog/python-assert-tutorial) to check whether a condition is met and let Python raise the `AssertionError` if the condition isnât met.
The idea of an assertion is that your program should only attempt to run if certain conditions are in place. If Python checks your assertion and finds that the condition is `True`, then that is excellent! The program can continue. If the condition turns out to be `False`, then your program raises an `AssertionError` exception and stops right away:
[](https://files.realpython.com/media/assert.f6d344f0c0b4.png)
Revisit your tiny script, `low.py`, from [the previous section](https://realpython.com/python-exceptions/#raising-an-exception-in-python). Currently, youâre explicitly raising an exception when a certain condition isnât met:
Python `low.py`
```
```
Assuming that youâll handle this constraint safely for your production system, you could replace this [conditional statement](https://realpython.com/python-conditional-statements/) with an assertion for a quick way to retain this sanity check during development:
Python `low.py`
```
```
If the `number` in your program is below `5`, then the assertion passes and your script continues with the next line of code. However, if you set `number` to a value higher than `5`âfor example, `10`âthen the outcome of the assertion will be `False`:
Python `low.py`
```
```
In that case, Python raises an `AssertionError` that includes the message you passed, and ends the program execution:
Shell
```
```
In this example, raising an `AssertionError` exception is the last thing that the program will do. The program will then come to halt and wonât continue. The call to `print()` that follows the assertion wonât execute.
Using assertions in this way can be helpful when youâre debugging your program during development because it can be quite a fast and straightforward to add assertions into your code.
However, you shouldnât rely on assertions for catching crucial run conditions of your program in production. Thatâs because Python globally disables assertions when you run it in optimized mode using the [`-O` and `-OO` command line options](https://docs.python.org/3/using/cmdline.html#cmdoption-O):
Shell
```
```
In this run of your program, you used the `-O` command line option, which removes all `assert` statements. Therefore, your script ran all the way to the end and displayed a number that is *dreadfully* high\!
**Note:** Alternatively, you can also disable assertions through the [`PYTHONOPTIMIZE` environment variable](https://docs.python.org/3/using/cmdline.html#envvar-PYTHONOPTIMIZE).
In production, your Python code may run using this optimized mode, which means that assertions arenât a reliable way to handle runtime errors in production code. They can be quick and useful helpers when your debugging your code, but you should never use assertions to set crucial constraints for your program.
If `low.py` should reliably fail when `number` is above `5`, then itâs best to stick with [raising an exception](https://realpython.com/python-exceptions/#raising-an-exception-in-python). However, sometimes you might not want your program to fail when it encounters an exception, so how should you handle those situations?
[Remove ads](https://realpython.com/account/join/)
## Handling Exceptions With the `try` and `except` Block
In Python, you use the `try` and `except` block to catch and handle exceptions. Python executes code following the `try` statement as a normal part of the program. The code that follows the `except` statement is the programâs response to any exceptions in the preceding `try` clause:
[](https://files.realpython.com/media/try_except.c94eabed2c59.png)
As you saw earlier, when syntactically correct code runs into an error, Python will raise an exception error. This exception error will crash the program if you donât handle it. In the `except` clause, you can determine how your program should respond to exceptions.
The following function can help you understand the `try` and `except` block:
Python `linux_interaction.py`
```
```
The `linux_interaction()` can only run on a Linux system. Python will raise a `RuntimeError` exception if you call it on an operating system other then Linux.
**Note:** Picking the right exception type can sometimes be tricky. Python comes with [many built-in exceptions](https://docs.python.org/3/library/exceptions.html#concrete-exceptions) that are [hierarchically related](https://docs.python.org/3/library/exceptions.html#exception-hierarchy), so if you browse the documentation, youâre likely to find a fitting one.
Python even groups some of the exceptions into categories, such as [warnings](https://docs.python.org/3/library/exceptions.html#warnings) that you should use to indicate warning conditions, and [OS exceptions](https://docs.python.org/3/library/exceptions.html#os-exceptions) that Python raises depending on system error codes.
If you still didnât find a fitting exception, then you can [create a custom exception](https://realpython.com/python-exceptions/#creating-custom-exceptions-in-python).
You can give the function a `try` by adding the following code:
Python `linux_interaction.py`
```
```
The way you handled the error here is by handing out a `pass`. If you run this code on a macOS or Windows machine, then you get the following output:
Shell
```
$ python linux_interaction.py
```
You got nothing in response. The good thing here is that your program didnât crash. But letting an exception that occurred pass silently is bad practice. You should always at least know about and [log](https://realpython.com/python-logging/) if some type of exception occurred when you ran your code.
To this end, you can change `pass` into something that generates an informative message:
Python `linux_interaction.py`
```
```
When you now execute this code on a macOS or Windows machine, youâll see the message from your `except` block printed to the console:
Shell
```
```
When an exception occurs in a program that runs this function, then the program will continue as well as inform you about the fact that the function call wasnât successful.
What you didnât get to see was the type of error that Python raised as a result of the function call. In order to see exactly what went wrong, youâd need to catch the error that the function raised.
The following code is an example where you capture the `RuntimeError` and output that message to your screen:
Python `linux_interaction.py`
```
```
In the `except` clause, you assign the `RuntimeError` to the temporary variable `error`âoften also called `err`âso that you can access the exception object in the indented block. In this case, youâre printing the objectâs string representation, which corresponds to the error message attached to the object.
Running this function on a macOS or Windows machine outputs the following:
Shell
```
```
The first message is the `RuntimeError`, informing you that Python can only execute the function on a Linux machine. The second message tells you which function wasnât executed.
In the example above, you called a function that you wrote yourself. When you executed the function, you caught the `RuntimeError` exception and printed it to your screen.
Hereâs another example where you open a file and use a built-in exception:
Python `open_file.py`
```
```
If `file.log` doesnât exist, then this block of code will output the following:
Shell
```
```
This is an informative message, and your program will still continue to run. However, your `except` block will currently catch *any* exception, whether thatâs related to not being able to open the file or not. You could lead yourself onto a confusing path if you see this message even when Python raises a completely unrelated exception.
Therefore, itâs always best to be *specific* when youâre handling an exception.
In the [Python docs](https://docs.python.org/3/library/exceptions.html), you can see that there are a couple of built-in exceptions that you could raise in such a situation, for example:
> *exception* `FileNotFoundError`
>
> Raised when a file or directory is requested but doesnât exist. Corresponds to errno ENOENT. ([Source](https://docs.python.org/3/library/exceptions.html#FileNotFoundError))
You want to handle the situation when Python canât find the requested file. To catch this type of exception and print it to screen, you could use the following code:
Python `open_file.py`
```
```
In this case, if `file.log` doesnât exist, then the output will be the following:
Shell
```
```
You can have more than one function call in your `try` clause and anticipate catching various exceptions. Something to note here is that the code in the `try` clause will stop as soon as it encounters any one exception.
**Warning:** When you use a bare `except` clause, then Python catches any exception that inherits from `Exception`âwhich are most built-in exceptions! Catching the parent class, `Exception`, hides all errorsâeven those which you didnât expect at all. This is why you should avoid bare `except` clauses in your Python programs.
Instead, youâll want to refer to *specific exception classes* that you want to catch and handle. You can learn more about why this is a good idea [in this tutorial](https://realpython.com/the-most-diabolical-python-antipattern/).
Look at the following code. Here, you first call `linux_interaction()` and then try to open a file:
Python `linux_interaction.py`
```
```
If you run this code on a macOS or Windows machine, then youâll see the following:
Shell
```
```
Inside the `try` clause, you ran into an exception immediately and didnât get to the part where you attempt to open `file.log`. Now look at what happens when you run the code on a Linux machine if the file doesnât exist:
Shell
```
```
Note that if youâre handling specific exceptions as you did above, then the order of the `except` clauses doesnât matter too much. Itâs all about which of the exceptions Python raises first. As soon as Python raises an exception, it checks the except clauses from top to bottom and executes the first matching one that it finds.
Here are the key takeaways about using Pythonâs `try` ⊠`except` statements:
- Python executes a `try` clause up until the point where it encounters the first exception.
- Inside the `except` clauseâthe exception handlerâyou determine how the program responds to the exception.
- You can anticipate [multiple exceptions](https://realpython.com/python-catch-multiple-exceptions/) and differentiate how the program should respond to them.
- [Avoid using bare `except` clauses](https://realpython.com/the-most-diabolical-python-antipattern/), because they can hide unexpected exceptions.
While using `try` together with `except` is probably the most common error handling that youâll encounter, thereâs more that you can do to fine-tune your programâs response to exceptions.
[Remove ads](https://realpython.com/account/join/)
## Proceeding After a Successful Try With `else`
You can use Pythonâs `else` statement to instruct a program to execute a certain block of code only in the absence of exceptions:
[](https://files.realpython.com/media/try_except_else.703aaeeb63d3.png)
Look at the following example:
Python `linux_interaction.py`
```
```
If you were to run this code on a Linux system, then the output would be the following:
Shell
```
```
Because the program didnât run into *any* exceptions, Python executed the code in the `else` clause. However, if you run this code on a macOS or Windows system, then you get a different output:
Shell
```
```
The `linux_interaction()` function raised a `RuntimeError`. Youâve handled the exception, so your program doesnât crash, and instead prints the exception message to the console. The code nested under the `else` clause, however, doesnât execute, because Python encountered an exception during execution.
Note that structuring your code like this is different from just adding the call to `print()` outside of the context of the `try` ⊠`except` block:
Python `linux_interaction.py`
```
```
If you donât nest the `print()` call under the `else` clause, then itâll execute even if Python encounters the `RuntimeError` that you handle in the `except` block above. On a Linux system, the output would be the same, but on macOS or Windows, youâd get the following output:
Shell
```
```
Nesting code under the `else` clause assures that itâll only run when Python doesnât encounter any exception when executing the `try` ⊠`except` block.
You can also create a nested `try` ⊠`except` block inside the `else` clause and catch possible exceptions there as well:
Python `linux_interaction.py`
```
```
If you were to execute this code on a Linux machine, then youâd get the following result:
Shell
```
```
From the output, you can see that `linux_interaction()` ran. Because Python encountered no exceptions, it attempted to open `file.log`. That file didnât exist, but instead of letting the program crash, you caught the `FileNotFoundError` exception and printed a message to the console.
[Remove ads](https://realpython.com/account/join/)
## Cleaning Up After Execution With `finally`
Imagine that you always had to implement some sort of action to clean up after executing your code. Python enables you to do so using the `finally` clause:
[](https://files.realpython.com/media/try_except_else_finally.a7fac6c36c55.png)
Have a look at the following example:
Python `linux_interaction.py`
```
```
In this code, Python will execute everything in the `finally` clause. It doesnât matter if you encounter an exception somewhere in any of the `try` ⊠`except` blocks. Running the code on a macOS or Windows machine will output the following:
Shell
```
```
Note that the code inside the `finally` block will execute regardless of whether or not youâre handling the exceptions:
Python `linux_interaction.py`
```
```
You simplified the example code from above, but `linux_interaction()` still raises an exception on a macOS or Windows system. If you now run this code on an operating system other than Linux, then youâll get the following output:
Shell
```
```
Despite the fact that Python raised the `RuntimeError`, the code in the `finally` clause still executed and printed the message to your console.
This can be helpful because even code outside of a `try`⊠`except` block wonât necessarily execute if your script encounters an unhandled exception. In that case, your program will terminate and the code *after* the `try` ⊠`except` block will never run. However, Python will still execute the code inside of the `finally` clause. This helps you make sure that resources like [file handles](https://realpython.com/why-close-file-python/) and [database connections](https://realpython.com/python-sql-libraries/) are cleaned up properly.
## Creating Custom Exceptions in Python
With the large number of built-in exceptions that Python offers, youâll likely find a fitting type when deciding which exception to raise. However, sometimes your code wonât fit the mold.
Python makes it straightforward to create custom exception types by inheriting from a built-in exception. Think back to your `linux_interaction()` function:
Python `linux_interaction.py`
```
```
Using a [`RuntimeError`](https://docs.python.org/3/library/exceptions.html#RuntimeError) isnât a bad choice in this situation, but it would be nice if your exception name was a bit more specific. For this, you can create a custom exception:
Python `linux_interaction.py`
```
```
You generally create a custom exception in Python by inheriting from `Exception`, which is the base class for most built-in Python exceptions as well. You could also inherit from a different exception, but choosing `Exception` is usually the best choice.
Thatâs really all that you need to do. In the code snippet above, you also added a [docstring](https://realpython.com/documenting-python-code/) that describes the exception type and serves as the class body.
**Note:** Python requires some indented code in the body of your class. Alternatively to using the docstring, you couldâve also used [`pass`](https://realpython.com/python-pass/) or [the ellipsis (`...`)](https://realpython.com/python-ellipsis/). However, adding a descriptive docstring adds the most value to your custom exception. To learn how to write effective docstrings, check out [How to Write Docstrings in Python](https://realpython.com/how-to-write-docstrings-in-python/).
While you can customize your exception object, you donât need to do that. Itâs often enough to give your custom Python exceptions a descriptive name, so youâll know what happened when Python raises this exception in your code.
Now that youâve defined the custom exception, you can raise it like any other Python exception:
Python `linux_interaction.py`
```
```
If you now call `linux_interaction()` on macOS or Windows, then youâll see that Python raises your custom exception:
Shell
```
```
You could even use your custom `PlatformException` as a parent class for other custom exceptions that you could descriptively name for each of the platforms that users may run your code on.
[Remove ads](https://realpython.com/account/join/)
## Conclusion
At this point, youâre familiar with the basics of using Python exceptions. After seeing the difference between syntax errors and exceptions, you learned about various ways to raise, catch, and handle exceptions in Python. You also learned how you can create your own custom exceptions.
In this article, you gained experience working with the following exception-related keywords:
- `raise` allows you to raise an exception at any time.
- `assert` enables you to verify if a certain condition is met and raises an exception if it isnât.
- In the `try` clause, all statements are executed until an exception is encountered.
- `except` allows you to catch and handle the exception or exceptions that Python encountered in the `try` clause.
- `else` lets you code sections that should run only when Python encounters no exceptions in the `try` clause.
- `finally` enables you to execute sections of code that should always run, whether or not Python encountered any exceptions.
**Get Your Code:** [Click here to download the free sample code](https://realpython.com/bonus/python-exceptions-code/) that shows you how exceptions work in Python.
You now understand the basic tools that Python offers for dealing with exceptions. If youâre curious about the topic and want to dive deeper, then take a look at the following tutorials:
- [Pythonâs Built-in Exceptions: A Walkthrough With Examples](https://realpython.com/python-built-in-exceptions/)
- [Exception Groups and `except*`](https://realpython.com/python311-exception-groups/#exception-groups-and-except-in-python-311)
- [Python `raise`: Effectively Raising Exceptions in Your Code](https://realpython.com/python-raise-exception/)
- [How to Catch Multiple Exception in Python](https://realpython.com/python-catch-multiple-exceptions/)
- [Understanding the Python Traceback](https://realpython.com/python-traceback/)
- [LBYL vs EAFP: Preventing or Handling Errors in Python](https://realpython.com/python-lbyl-vs-eafp/)
Whatâs your favorite aspect of exception handling in Python? Share your thoughts in the comments below.
## Frequently Asked Questions
Now that you have some experience with Python exceptions, you can use the questions and answers below to check your understanding and recap what youâve learned.
These FAQs are related to the most important concepts youâve covered in this tutorial. Click the *Show/Hide* toggle beside each question to reveal the answer.
****What are exceptions in Python?****Show/Hide
Exceptions in Python are errors that occur during the execution of a program, disrupting the normal flow of the program.
****How are exceptions handled in Python?****Show/Hide
You handle exceptions in Python using a `try` ⊠`except` block. Python executes the code in the `try` block and if an exception occurs, it switches to executing the code in the `except` block to handle the exception. However, only the exceptions that are explicitly specified in the `except` block will be handled. If an exception is not caught, itâll propagate up the call stack and may result in the termination of your program.
****How do you catch all exceptions in Python?****Show/Hide
To catch all exceptions in Python, you can use a bare `except` clause or write `except Exception`, but itâs recommended to catch specific exceptions to avoid masking unexpected errors.
****How does `try` ⊠`except` in Python work?****Show/Hide
In a `try` ⊠`except` block, Python executes the code under `try` and if an exception occurs, it immediately jumps to the `except` block to handle it, allowing the program to continue running.
****What does `try` ⊠`except` `pass` do in Python?****Show/Hide
Using `try` ⊠`except` with `pass` allows the program to ignore the exception and continue execution without taking any specific action in response to the error. However, this practice can hide potential issues, making it harder to debug and maintain the code, so use it with caution. Itâs generally better to either handle the exception explicitly or log it for debugging purposes.
****How do you raise an exception in Python?****Show/Hide
You raise an exception in Python using the `raise` keyword followed by an exception object, which can include a custom message.
****What is the purpose of using `assert` in Python?****Show/Hide
You can use the `assert` keyword to check if a condition is true during development. If the condition is false, it raises an `AssertionError`, which can help with debugging. Note that assertions can be disabled by running Python with the `-O` (optimize) flag. Therefore, you shouldnât rely on assertions for critical checks in production code, as they may be ignored.
****What is the role of the `finally` clause in exception handling?****Show/Hide
The `finally` clause contains code that will always execute after a `try` block, regardless of whether an exception was raised or not, ensuring necessary cleanup actions occur.
***Take the Quiz:*** Test your knowledge with our interactive âPython Exceptions: An Introductionâ quiz. Youâll receive a score upon completion to help you track your learning progress:
***
[](https://realpython.com/quizzes/python-exceptions/)
**Interactive Quiz**
[Python Exceptions: An Introduction](https://realpython.com/quizzes/python-exceptions/)
In this quiz, you'll test your understanding of Python exceptions. You'll cover the difference between syntax errors and exceptions and learn how to raise exceptions, make assertions, and use the try and except block.
Mark as Completed
Share
Recommended Courses
[Raising and Handling Python Exceptions](https://realpython.com/courses/raising-handling-exceptions/) (1h 2m)
1 more course
- [Introduction to Python Exceptions](https://realpython.com/courses/introduction-python-exceptions/) (13m)
đ Python Tricks đ
Get a short & sweet **Python Trick** delivered to your inbox every couple of days. No spam ever. Unsubscribe any time. Curated by the Real Python team.

About **Said van de Klundert**
[ ](https://realpython.com/team/svdklundert/)
Said is a network engineer, Python enthusiast, and a guest author at Real Python.
[» More about Said](https://realpython.com/team/svdklundert/)
***
*Each tutorial at Real Python is created by a team of developers so that it meets our high quality standards. The team members who worked on this tutorial are:*
[](https://realpython.com/team/acutenco/)
[Adriana](https://realpython.com/team/acutenco/)
[](https://realpython.com/team/bweleschuk/)
[Brenda](https://realpython.com/team/bweleschuk/)
[](https://realpython.com/team/bzaczynski/)
[Bartosz](https://realpython.com/team/bzaczynski/)
[](https://realpython.com/team/gahjelle/)
[Geir Arne](https://realpython.com/team/gahjelle/)
[](https://realpython.com/team/jjablonski/)
[Joanna](https://realpython.com/team/jjablonski/)
[](https://realpython.com/team/kfinegan/)
[Kate](https://realpython.com/team/kfinegan/)
[](https://realpython.com/team/mbreuss/)
[Martin](https://realpython.com/team/mbreuss/)
Master Real-World Python Skills With Unlimited Access to Real Python

**Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:**
[Level Up Your Python Skills »](https://realpython.com/account/join/?utm_source=rp_article_footer&utm_content=python-exceptions)
Master Real-World Python Skills
With Unlimited Access to Real Python

**Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:**
[Level Up Your Python Skills »](https://realpython.com/account/join/?utm_source=rp_article_footer&utm_content=python-exceptions)
What Do You Think?
**Rate this article:**
[LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Frealpython.com%2Fpython-exceptions%2F)
[Twitter](https://twitter.com/intent/tweet/?text=Interesting%20Python%20article%20on%20%40realpython%3A%20Python%20Exceptions%3A%20An%20Introduction&url=https%3A%2F%2Frealpython.com%2Fpython-exceptions%2F)
[Bluesky](https://bsky.app/intent/compose?text=Interesting%20Python%20article%20on%20%40realpython.com%3A%20Python%20Exceptions%3A%20An%20Introduction%20https%3A%2F%2Frealpython.com%2Fpython-exceptions%2F)
[Facebook](https://facebook.com/sharer/sharer.php?u=https%3A%2F%2Frealpython.com%2Fpython-exceptions%2F)
[Email](mailto:?subject=Python%20article%20for%20you&body=Python%20Exceptions%3A%20An%20Introduction%20on%20Real%20Python%0A%0Ahttps%3A%2F%2Frealpython.com%2Fpython-exceptions%2F%0A)
Whatâs your \#1 takeaway or favorite thing you learned? How are you going to put your newfound skills to use? Leave a comment below and let us know.
**Commenting Tips:** The most useful comments are those written with the goal of learning from or helping out other students. [Get tips for asking good questions](https://realpython.com/python-beginner-tips/#tip-9-ask-good-questions) and [get answers to common questions in our support portal](https://support.realpython.com/).
***
Looking for a real-time conversation? Visit the [Real Python Community Chat](https://realpython.com/community/) or join the next [âOffice Hoursâ Live Q\&A Session](https://realpython.com/office-hours/). Happy Pythoning\!
Keep Learning
Related Topics: [basics](https://realpython.com/tutorials/basics/) [python](https://realpython.com/tutorials/python/)
Related Learning Paths:
- [Exceptions, Logging, and Debugging](https://realpython.com/learning-paths/exception-handling-logging-debugging/?utm_source=realpython&utm_medium=web&utm_campaign=related-learning-path&utm_content=python-exceptions)
- [Revisit Python Fundamentals](https://realpython.com/learning-paths/python3-introduction/?utm_source=realpython&utm_medium=web&utm_campaign=related-learning-path&utm_content=python-exceptions)
Related Courses:
- [Raising and Handling Python Exceptions](https://realpython.com/courses/raising-handling-exceptions/?utm_source=realpython&utm_medium=web&utm_campaign=related-course&utm_content=python-exceptions)
- [Introduction to Python Exceptions](https://realpython.com/courses/introduction-python-exceptions/?utm_source=realpython&utm_medium=web&utm_campaign=related-course&utm_content=python-exceptions)
Related Tutorials:
- [Defining Your Own Python Function](https://realpython.com/defining-your-own-python-function/?utm_source=realpython&utm_medium=web&utm_campaign=related-post&utm_content=python-exceptions)
- [Reading and Writing Files in Python (Guide)](https://realpython.com/read-write-files-python/?utm_source=realpython&utm_medium=web&utm_campaign=related-post&utm_content=python-exceptions)
- [Python's Built-in Exceptions: A Walkthrough With Examples](https://realpython.com/python-built-in-exceptions/?utm_source=realpython&utm_medium=web&utm_campaign=related-post&utm_content=python-exceptions)
- [Object-Oriented Programming (OOP) in Python](https://realpython.com/python3-object-oriented-programming/?utm_source=realpython&utm_medium=web&utm_campaign=related-post&utm_content=python-exceptions)
- [Dictionaries in Python](https://realpython.com/python-dicts/?utm_source=realpython&utm_medium=web&utm_campaign=related-post&utm_content=python-exceptions)
## Keep reading Real Python by creating a free account or signing in:
[](https://realpython.com/account/signup/?intent=continue_reading&utm_source=rp&utm_medium=web&utm_campaign=rwn&utm_content=v1&next=%2Fpython-exceptions%2F)
[Continue »](https://realpython.com/account/signup/?intent=continue_reading&utm_source=rp&utm_medium=web&utm_campaign=rwn&utm_content=v1&next=%2Fpython-exceptions%2F)
Already have an account? [Sign-In](https://realpython.com/account/login/?next=/python-exceptions/)
Almost there! Complete this form and click the button below to gain instant access:
Ă

Python Exceptions: An Introduction (Sample Code)
##### Learn Python
- [Start Here](https://realpython.com/start-here/)
- [Learning Resources](https://realpython.com/search)
- [Code Mentor](https://realpython.com/mentor/)
- [Python Reference](https://realpython.com/ref/)
- [Python Cheat Sheet](https://realpython.com/cheatsheets/python/)
- [Support Center](https://support.realpython.com/)
##### Courses & Paths
- [Learning Paths](https://realpython.com/learning-paths/)
- [Quizzes & Exercises](https://realpython.com/quizzes/)
- [Browse Topics](https://realpython.com/tutorials/all/)
- [Live Courses](https://realpython.com/live/)
- [Books](https://realpython.com/books/)
##### Community
- [Podcast](https://realpython.com/podcasts/rpp/)
- [Newsletter](https://realpython.com/newsletter/)
- [Community Chat](https://realpython.com/community/)
- [Office Hours](https://realpython.com/office-hours/)
- [Learner Stories](https://realpython.com/learner-stories/)
##### Membership
- [Plans & Pricing](https://realpython.com/account/join/)
- [Team Plans](https://realpython.com/account/join-team/)
- [For Business](https://realpython.com/account/join-team/inquiry/)
- [For Schools](https://realpython.com/account/join-team/education-inquiry/)
- [Reviews](https://realpython.com/learner-stories/)
##### Company
- [About Us](https://realpython.com/about/)
- [Team](https://realpython.com/team/)
- [Mission & Values](https://realpython.com/mission/)
- [Editorial Guidelines](https://realpython.com/editorial-guidelines/)
- [Sponsorships](https://realpython.com/sponsorships/)
- [Careers](https://realpython.workable.com/)
- [Press Kit](https://realpython.com/media-kit/)
- [Merch](https://realpython.com/merch)
[Privacy Policy](https://realpython.com/privacy-policy/) â
[Terms of Use](https://realpython.com/terms/) â
[Security](https://realpython.com/security/) â
[Contact](https://realpython.com/contact/)
Happy Pythoning\!
© 2012â2026 DevCademy Media Inc. DBA Real Python. All rights reserved.
REALPYTHONâą is a trademark of DevCademy Media Inc.
[](https://realpython.com/)

You've blocked notifications |
| Readable Markdown | by [Said van de Klundert](https://realpython.com/python-exceptions/#author) Reading time estimate 24m [basics](https://realpython.com/tutorials/basics/) [python](https://realpython.com/tutorials/python/)
Python exceptions provide a mechanism for handling errors that occur during the execution of a program. Unlike syntax errors, which are detected by the parser, Python raises exceptions when an error occurs in syntactically correct code. Knowing how to raise, catch, and handle exceptions effectively helps to ensure your program behaves as expected, even when encountering errors.
**By the end of this tutorial, youâll understand that:**
- Exceptions in Python occur when **syntactically correct code** results in an **error**.
- **The `try` ⊠`except` block** lets you execute code and handle exceptions that arise.
- You can use the `else`, and `finally` **keywords** for more refined **exception handling**.
- Itâs **bad practice** to **catch all exceptions** at once using `except Exception` or the bare `except` clause.
- Combining `try`, `except`, and `pass` allows your program to **continue silently** without handling the exception.
In this tutorial, youâll get to know Python exceptions and all relevant keywords for exception handling by walking through a practical example of handling a platform-related exception. Finally, youâll also learn how to create your own custom Python exceptions.
***Take the Quiz:*** Test your knowledge with our interactive âPython Exceptions: An Introductionâ quiz. Youâll receive a score upon completion to help you track your learning progress:
***
[](https://realpython.com/quizzes/python-exceptions/)
**Interactive Quiz**
[Python Exceptions: An Introduction](https://realpython.com/quizzes/python-exceptions/)
In this quiz, you'll test your understanding of Python exceptions. You'll cover the difference between syntax errors and exceptions and learn how to raise exceptions, make assertions, and use the try and except block.
## Understanding Exceptions and Syntax Errors
[Syntax errors](https://realpython.com/invalid-syntax-python/) occur when the parser detects an incorrect statement. Observe the following example:
The arrow indicates where the parser ran into the **syntax error**. Additionally, the error message gives you a hint about what went wrong. In this example, there was one bracket too many. Remove it and run your code again:
This time, you ran into an **exception error**. This type of error occurs whenever syntactically correct Python code results in an error. The last line of the message indicates what type of exception error you ran into.
Instead of just writing *exception error*, Python details what *type* of exception error it encountered. In this case, it was a `ZeroDivisionError`. Python comes with [various built-in exceptions](https://docs.python.org/3/library/exceptions.html) as well as the possibility to create user-defined exceptions.
## Raising an Exception in Python
There are scenarios where you might want to stop your program by raising an exception if a condition occurs. You can do this with the [`raise`](https://realpython.com/python-raise-exception/) keyword:
[](https://files.realpython.com/media/raise.3931e8819e08.png)
You can even complement the statement with a custom message. Assume that youâre writing a tiny toy program that expects only numbers up to `5`. You can raise an error when an unwanted condition occurs:
In this example, you raised an `Exception` object and passed it an informative custom message. You built the message using an [f-string](https://realpython.com/python-f-strings/) and a [self-documenting expression](https://realpython.com/python-f-strings/#self-documenting-expressions-for-debugging).
When you run `low.py`, youâll get the following output:
The program comes to a halt and displays the exception to your [terminal](https://realpython.com/terminal-commands/) or [REPL](https://realpython.com/python-repl/), offering you helpful clues about what went wrong. Note that the final call to [`print()`](https://realpython.com/python-print/) never executed, because Python raised the exception before it got to that line of code.
With the `raise` keyword, you can raise any exception object in Python and stop your program when an unwanted condition occurs.
## Debugging During Development With `assert`
Before moving on to the most common way of working with exceptions in Python using [the `try` ⊠`except` block](https://realpython.com/python-exceptions/#handling-exceptions-with-the-try-and-except-block), youâll take a quick look at an exception thatâs a bit different than the others.
Python offers a specific exception type that you should only use when debugging your program during development. This exception is the `AssertionError`. The `AssertionError` is special because you shouldnât ever raise it yourself using `raise`.
Instead, you use [the `assert` keyword](https://dbader.org/blog/python-assert-tutorial) to check whether a condition is met and let Python raise the `AssertionError` if the condition isnât met.
The idea of an assertion is that your program should only attempt to run if certain conditions are in place. If Python checks your assertion and finds that the condition is `True`, then that is excellent! The program can continue. If the condition turns out to be `False`, then your program raises an `AssertionError` exception and stops right away:
[](https://files.realpython.com/media/assert.f6d344f0c0b4.png)
Revisit your tiny script, `low.py`, from [the previous section](https://realpython.com/python-exceptions/#raising-an-exception-in-python). Currently, youâre explicitly raising an exception when a certain condition isnât met:
Assuming that youâll handle this constraint safely for your production system, you could replace this [conditional statement](https://realpython.com/python-conditional-statements/) with an assertion for a quick way to retain this sanity check during development:
If the `number` in your program is below `5`, then the assertion passes and your script continues with the next line of code. However, if you set `number` to a value higher than `5`âfor example, `10`âthen the outcome of the assertion will be `False`:
In that case, Python raises an `AssertionError` that includes the message you passed, and ends the program execution:
In this example, raising an `AssertionError` exception is the last thing that the program will do. The program will then come to halt and wonât continue. The call to `print()` that follows the assertion wonât execute.
Using assertions in this way can be helpful when youâre debugging your program during development because it can be quite a fast and straightforward to add assertions into your code.
However, you shouldnât rely on assertions for catching crucial run conditions of your program in production. Thatâs because Python globally disables assertions when you run it in optimized mode using the [`-O` and `-OO` command line options](https://docs.python.org/3/using/cmdline.html#cmdoption-O):
In this run of your program, you used the `-O` command line option, which removes all `assert` statements. Therefore, your script ran all the way to the end and displayed a number that is *dreadfully* high\!
In production, your Python code may run using this optimized mode, which means that assertions arenât a reliable way to handle runtime errors in production code. They can be quick and useful helpers when your debugging your code, but you should never use assertions to set crucial constraints for your program.
If `low.py` should reliably fail when `number` is above `5`, then itâs best to stick with [raising an exception](https://realpython.com/python-exceptions/#raising-an-exception-in-python). However, sometimes you might not want your program to fail when it encounters an exception, so how should you handle those situations?
## Handling Exceptions With the `try` and `except` Block
In Python, you use the `try` and `except` block to catch and handle exceptions. Python executes code following the `try` statement as a normal part of the program. The code that follows the `except` statement is the programâs response to any exceptions in the preceding `try` clause:
[](https://files.realpython.com/media/try_except.c94eabed2c59.png)
As you saw earlier, when syntactically correct code runs into an error, Python will raise an exception error. This exception error will crash the program if you donât handle it. In the `except` clause, you can determine how your program should respond to exceptions.
The following function can help you understand the `try` and `except` block:
The `linux_interaction()` can only run on a Linux system. Python will raise a `RuntimeError` exception if you call it on an operating system other then Linux.
You can give the function a `try` by adding the following code:
The way you handled the error here is by handing out a `pass`. If you run this code on a macOS or Windows machine, then you get the following output:
You got nothing in response. The good thing here is that your program didnât crash. But letting an exception that occurred pass silently is bad practice. You should always at least know about and [log](https://realpython.com/python-logging/) if some type of exception occurred when you ran your code.
To this end, you can change `pass` into something that generates an informative message:
When you now execute this code on a macOS or Windows machine, youâll see the message from your `except` block printed to the console:
When an exception occurs in a program that runs this function, then the program will continue as well as inform you about the fact that the function call wasnât successful.
What you didnât get to see was the type of error that Python raised as a result of the function call. In order to see exactly what went wrong, youâd need to catch the error that the function raised.
The following code is an example where you capture the `RuntimeError` and output that message to your screen:
In the `except` clause, you assign the `RuntimeError` to the temporary variable `error`âoften also called `err`âso that you can access the exception object in the indented block. In this case, youâre printing the objectâs string representation, which corresponds to the error message attached to the object.
Running this function on a macOS or Windows machine outputs the following:
The first message is the `RuntimeError`, informing you that Python can only execute the function on a Linux machine. The second message tells you which function wasnât executed.
In the example above, you called a function that you wrote yourself. When you executed the function, you caught the `RuntimeError` exception and printed it to your screen.
Hereâs another example where you open a file and use a built-in exception:
If `file.log` doesnât exist, then this block of code will output the following:
This is an informative message, and your program will still continue to run. However, your `except` block will currently catch *any* exception, whether thatâs related to not being able to open the file or not. You could lead yourself onto a confusing path if you see this message even when Python raises a completely unrelated exception.
Therefore, itâs always best to be *specific* when youâre handling an exception.
In the [Python docs](https://docs.python.org/3/library/exceptions.html), you can see that there are a couple of built-in exceptions that you could raise in such a situation, for example:
> *exception* `FileNotFoundError`
>
> Raised when a file or directory is requested but doesnât exist. Corresponds to errno ENOENT. ([Source](https://docs.python.org/3/library/exceptions.html#FileNotFoundError))
You want to handle the situation when Python canât find the requested file. To catch this type of exception and print it to screen, you could use the following code:
In this case, if `file.log` doesnât exist, then the output will be the following:
You can have more than one function call in your `try` clause and anticipate catching various exceptions. Something to note here is that the code in the `try` clause will stop as soon as it encounters any one exception.
Look at the following code. Here, you first call `linux_interaction()` and then try to open a file:
If you run this code on a macOS or Windows machine, then youâll see the following:
Inside the `try` clause, you ran into an exception immediately and didnât get to the part where you attempt to open `file.log`. Now look at what happens when you run the code on a Linux machine if the file doesnât exist:
Note that if youâre handling specific exceptions as you did above, then the order of the `except` clauses doesnât matter too much. Itâs all about which of the exceptions Python raises first. As soon as Python raises an exception, it checks the except clauses from top to bottom and executes the first matching one that it finds.
Here are the key takeaways about using Pythonâs `try` ⊠`except` statements:
- Python executes a `try` clause up until the point where it encounters the first exception.
- Inside the `except` clauseâthe exception handlerâyou determine how the program responds to the exception.
- You can anticipate [multiple exceptions](https://realpython.com/python-catch-multiple-exceptions/) and differentiate how the program should respond to them.
- [Avoid using bare `except` clauses](https://realpython.com/the-most-diabolical-python-antipattern/), because they can hide unexpected exceptions.
While using `try` together with `except` is probably the most common error handling that youâll encounter, thereâs more that you can do to fine-tune your programâs response to exceptions.
## Proceeding After a Successful Try With `else`
You can use Pythonâs `else` statement to instruct a program to execute a certain block of code only in the absence of exceptions:
[](https://files.realpython.com/media/try_except_else.703aaeeb63d3.png)
Look at the following example:
If you were to run this code on a Linux system, then the output would be the following:
Because the program didnât run into *any* exceptions, Python executed the code in the `else` clause. However, if you run this code on a macOS or Windows system, then you get a different output:
The `linux_interaction()` function raised a `RuntimeError`. Youâve handled the exception, so your program doesnât crash, and instead prints the exception message to the console. The code nested under the `else` clause, however, doesnât execute, because Python encountered an exception during execution.
Note that structuring your code like this is different from just adding the call to `print()` outside of the context of the `try` ⊠`except` block:
If you donât nest the `print()` call under the `else` clause, then itâll execute even if Python encounters the `RuntimeError` that you handle in the `except` block above. On a Linux system, the output would be the same, but on macOS or Windows, youâd get the following output:
Nesting code under the `else` clause assures that itâll only run when Python doesnât encounter any exception when executing the `try` ⊠`except` block.
You can also create a nested `try` ⊠`except` block inside the `else` clause and catch possible exceptions there as well:
If you were to execute this code on a Linux machine, then youâd get the following result:
From the output, you can see that `linux_interaction()` ran. Because Python encountered no exceptions, it attempted to open `file.log`. That file didnât exist, but instead of letting the program crash, you caught the `FileNotFoundError` exception and printed a message to the console.
## Cleaning Up After Execution With `finally`
Imagine that you always had to implement some sort of action to clean up after executing your code. Python enables you to do so using the `finally` clause:
[](https://files.realpython.com/media/try_except_else_finally.a7fac6c36c55.png)
Have a look at the following example:
In this code, Python will execute everything in the `finally` clause. It doesnât matter if you encounter an exception somewhere in any of the `try` ⊠`except` blocks. Running the code on a macOS or Windows machine will output the following:
Note that the code inside the `finally` block will execute regardless of whether or not youâre handling the exceptions:
You simplified the example code from above, but `linux_interaction()` still raises an exception on a macOS or Windows system. If you now run this code on an operating system other than Linux, then youâll get the following output:
Despite the fact that Python raised the `RuntimeError`, the code in the `finally` clause still executed and printed the message to your console.
This can be helpful because even code outside of a `try`⊠`except` block wonât necessarily execute if your script encounters an unhandled exception. In that case, your program will terminate and the code *after* the `try` ⊠`except` block will never run. However, Python will still execute the code inside of the `finally` clause. This helps you make sure that resources like [file handles](https://realpython.com/why-close-file-python/) and [database connections](https://realpython.com/python-sql-libraries/) are cleaned up properly.
## Creating Custom Exceptions in Python
With the large number of built-in exceptions that Python offers, youâll likely find a fitting type when deciding which exception to raise. However, sometimes your code wonât fit the mold.
Python makes it straightforward to create custom exception types by inheriting from a built-in exception. Think back to your `linux_interaction()` function:
Using a [`RuntimeError`](https://docs.python.org/3/library/exceptions.html#RuntimeError) isnât a bad choice in this situation, but it would be nice if your exception name was a bit more specific. For this, you can create a custom exception:
You generally create a custom exception in Python by inheriting from `Exception`, which is the base class for most built-in Python exceptions as well. You could also inherit from a different exception, but choosing `Exception` is usually the best choice.
Thatâs really all that you need to do. In the code snippet above, you also added a [docstring](https://realpython.com/documenting-python-code/) that describes the exception type and serves as the class body.
While you can customize your exception object, you donât need to do that. Itâs often enough to give your custom Python exceptions a descriptive name, so youâll know what happened when Python raises this exception in your code.
Now that youâve defined the custom exception, you can raise it like any other Python exception:
If you now call `linux_interaction()` on macOS or Windows, then youâll see that Python raises your custom exception:
You could even use your custom `PlatformException` as a parent class for other custom exceptions that you could descriptively name for each of the platforms that users may run your code on.
## Conclusion
At this point, youâre familiar with the basics of using Python exceptions. After seeing the difference between syntax errors and exceptions, you learned about various ways to raise, catch, and handle exceptions in Python. You also learned how you can create your own custom exceptions.
In this article, you gained experience working with the following exception-related keywords:
- `raise` allows you to raise an exception at any time.
- `assert` enables you to verify if a certain condition is met and raises an exception if it isnât.
- In the `try` clause, all statements are executed until an exception is encountered.
- `except` allows you to catch and handle the exception or exceptions that Python encountered in the `try` clause.
- `else` lets you code sections that should run only when Python encounters no exceptions in the `try` clause.
- `finally` enables you to execute sections of code that should always run, whether or not Python encountered any exceptions.
You now understand the basic tools that Python offers for dealing with exceptions. If youâre curious about the topic and want to dive deeper, then take a look at the following tutorials:
- [Pythonâs Built-in Exceptions: A Walkthrough With Examples](https://realpython.com/python-built-in-exceptions/)
- [Exception Groups and `except*`](https://realpython.com/python311-exception-groups/#exception-groups-and-except-in-python-311)
- [Python `raise`: Effectively Raising Exceptions in Your Code](https://realpython.com/python-raise-exception/)
- [How to Catch Multiple Exception in Python](https://realpython.com/python-catch-multiple-exceptions/)
- [Understanding the Python Traceback](https://realpython.com/python-traceback/)
- [LBYL vs EAFP: Preventing or Handling Errors in Python](https://realpython.com/python-lbyl-vs-eafp/)
Whatâs your favorite aspect of exception handling in Python? Share your thoughts in the comments below.
## Frequently Asked Questions
Now that you have some experience with Python exceptions, you can use the questions and answers below to check your understanding and recap what youâve learned.
These FAQs are related to the most important concepts youâve covered in this tutorial. Click the *Show/Hide* toggle beside each question to reveal the answer.
Exceptions in Python are errors that occur during the execution of a program, disrupting the normal flow of the program.
You handle exceptions in Python using a `try` ⊠`except` block. Python executes the code in the `try` block and if an exception occurs, it switches to executing the code in the `except` block to handle the exception. However, only the exceptions that are explicitly specified in the `except` block will be handled. If an exception is not caught, itâll propagate up the call stack and may result in the termination of your program.
To catch all exceptions in Python, you can use a bare `except` clause or write `except Exception`, but itâs recommended to catch specific exceptions to avoid masking unexpected errors.
In a `try` ⊠`except` block, Python executes the code under `try` and if an exception occurs, it immediately jumps to the `except` block to handle it, allowing the program to continue running.
Using `try` ⊠`except` with `pass` allows the program to ignore the exception and continue execution without taking any specific action in response to the error. However, this practice can hide potential issues, making it harder to debug and maintain the code, so use it with caution. Itâs generally better to either handle the exception explicitly or log it for debugging purposes.
You raise an exception in Python using the `raise` keyword followed by an exception object, which can include a custom message.
You can use the `assert` keyword to check if a condition is true during development. If the condition is false, it raises an `AssertionError`, which can help with debugging. Note that assertions can be disabled by running Python with the `-O` (optimize) flag. Therefore, you shouldnât rely on assertions for critical checks in production code, as they may be ignored.
The `finally` clause contains code that will always execute after a `try` block, regardless of whether an exception was raised or not, ensuring necessary cleanup actions occur.
***Take the Quiz:*** Test your knowledge with our interactive âPython Exceptions: An Introductionâ quiz. Youâll receive a score upon completion to help you track your learning progress:
***
[](https://realpython.com/quizzes/python-exceptions/)
**Interactive Quiz**
[Python Exceptions: An Introduction](https://realpython.com/quizzes/python-exceptions/)
In this quiz, you'll test your understanding of Python exceptions. You'll cover the difference between syntax errors and exceptions and learn how to raise exceptions, make assertions, and use the try and except block. |
| Shard | 71 (laksa) |
| Root Hash | 13351397557425671 |
| Unparsed URL | com,realpython!/python-exceptions/ s443 |