Table of Contents
What Will You Learn
In this tutorial, you'll delve into Python's built-in exceptions, understanding their roles in error handling. You'll learn about the exception hierarchy, common exceptions like ValueError
, TypeError
, and KeyError
, and how to handle them using try-except
blocks. The guide also covers best practices for writing resilient Python code by effectively managing exceptions.
Python comes with a powerful set of built-in exceptions designed to catch and communicate errors in a clean, structured way. Learning how these exceptions work is crucial for every beginner. They allow your code to fail gracefully instead of crashing unexpectedly.
When you understand what each exception means, you can write better error-handling logic with try…except
and raise
. You’ll also debug faster, since
Python’s exception names clearly describe what went wrong — whether it’s a missing file, a wrong type, or a division by zero.
More importantly, using built-in exceptions improves your code’s readability and consistency. There's no need to reinvent the wheel by writing custom error messages when Python already gives you meaningful ones out of the box. Mastering these built-in tools is a key step toward writing clean, professional code.
What Are Some Common Built-in Exceptions in Python?
Python provides a wide range of built-in exceptions to help developers detect and handle different types of runtime errors. These include exceptions like
ValueError
, TypeError
, and FileNotFoundError
. Each exception is designed to describe a specific kind of problem that your code might
encounter.
For example, ValueError
is raised when a function receives an argument of the right type but an inappropriate value. TypeError
occurs when you use an
object in an invalid operation for its type. ZeroDivisionError
is raised when you attempt to divide a number by zero.
These exceptions are not just for catching mistakes — they’re essential tools for writing safe and maintainable code. Once you know what they mean, you’ll begin to anticipate issues before they happen.
Here are three practical examples:
# ValueError
int("abc") # Raises: ValueError – invalid literal for int()
# TypeError
"5" + 10 # Raises: TypeError – can't add str and int
# ZeroDivisionError
result = 5 / 0 # Raises: ZeroDivisionError – division by zero
By learning these built-in exceptions, you’ll write more predictable and bug-resistant programs.
How to Use raise
in Python with Built-in Exceptions?
The raise
keyword lets you manually trigger a built-in exception in Python. This is useful when you want to stop program execution and clearly communicate that
something went wrong. To use it, specify the exception class and provide a descriptive error message as an argument. This makes your code more reliable and easier to debug.
Raising built-in exceptions is a clean way to enforce rules in functions, validate data, or handle illegal operations. Below are three examples of raising common built-in exceptions.
# Raise a ValueError for invalid input
def set_age(age):
if age < 0:
raise ValueError("Age must be positive")
# Raise a TypeError if wrong data type is passed
def repeat(text, times):
if not isinstance(times, int):
raise TypeError("Repeat count must be an integer")
# Raise a FileNotFoundError manually
import os
def open_config(path):
if not os.path.exists(path):
raise FileNotFoundError("Configuration file not found")
These examples follow Python's built-in patterns and improve clarity in error handling.
Python Built-in Exceptions List
Python includes a large number of built-in exceptions that help describe specific error conditions. These exceptions are automatically raised by the interpreter when something goes wrong at runtime. They cover a wide range of common issues — from syntax errors to file access problems and invalid data types.
You can raise them manually using the
raise
keyword, or catch them usingtry…except
.
Below is a table with some of the most frequently used built-in exceptions in Python.
Exception | Description |
ValueError |
Raised when a function receives an inappropriate value. |
TypeError |
Raised when an operation is applied to an object of the wrong type. |
ZeroDivisionError |
Raised when a number is divided by zero. |
IndexError |
Raised when accessing an invalid list index. |
KeyError |
Raised when a key is not found in a dictionary. |
FileNotFoundError |
Raised when trying to access a file that doesn't exist. |
AttributeError |
Raised when an invalid attribute is accessed on an object. |
ImportError |
Raised when an import statement fails. |
StopIteration |
Raised to indicate no further items in an iterator. |
IndentationError |
Raised when indentation is incorrect. |
SyntaxError |
Raised when Python code contains a syntax mistake. |
MemoryError |
Raised when an operation runs out of memory. |
RuntimeError |
Raised for unspecified runtime errors. |
PermissionError |
Raised when an operation lacks the required access rights. |
AssertionError |
Raised when an assert statement fails. |
What Is the Base Class for All Built-in Exceptions in Python?
The base class for all built-in exceptions in Python is BaseException
. This is the root of the exception hierarchy, and every other exception class — including
Exception
— inherits from it either directly or indirectly. However, in everyday coding, developers typically use Exception
as the base class when
writing custom errors, because it excludes system-exit-related exceptions.
Understanding the hierarchy helps you catch exceptions correctly. For example, catching Exception
will ignore system-exit signals, while catching
BaseException
will catch everything — including KeyboardInterrupt
and SystemExit
, which is usually not recommended.
Here are three examples that reflect this hierarchy:
# All exceptions ultimately inherit from BaseException
print(issubclass(ValueError, BaseException)) # True
# Catching all exceptions (not always safe)
try:
exit()
except BaseException:
print("This catches even exit calls!")
# Custom exception should usually inherit from Exception, not BaseException
class MyAppError(Exception):
pass
Unless you have a specific need to handle system-level signals, always prefer Exception
over BaseException
.
Which of the Following Are Examples of Built-in Concrete Python Exceptions?
Concrete exceptions in Python are those you can directly raise or catch during program execution. These are fully defined classes in the standard library — not abstract or placeholder types. Most of the exceptions developers use daily are concrete.
Examples include IndexError
, ValueError
, and FileNotFoundError
. Each one is used to handle a specific, well-defined type of runtime error.
Unlike abstract exceptions, concrete ones can be instantiated and thrown with the raise
keyword.
Here are three typical concrete exception examples:
# IndexError example
my_list = [1, 2, 3]
print(my_list[5]) # Raises IndexError
# ValueError example
number = int("abc") # Raises ValueError
# FileNotFoundError example
open("missing.txt") # Raises FileNotFoundError
These built-in concrete exceptions should be part of every beginner’s Python toolkit.
Common Beginner Mistakes with Built-in Exceptions in Python
Catching All Exceptions with a Bare except:
One of the most dangerous mistakes is using a bare except:
without specifying an exception type. This will catch every exception, including system-exit exceptions
like KeyboardInterrupt
or SystemExit
. As a result, you might accidentally block termination signals or mask serious bugs.
# Bad
try:
1 / 0
except:
print("Something went wrong")
# Good
try:
1 / 0
except ZeroDivisionError:
print("Cannot divide by zero")
Catching the Wrong Exception Type
Beginners often guess the exception type instead of checking what Python actually throws. For example, catching TypeError
when the code raises a
ValueError
leads to unhandled exceptions. This causes confusion about why the except
block doesn't work.
# Incorrect
try:
int("abc")
except TypeError:
print("Wrong type") # Won’t run
# Correct
try:
int("abc")
except ValueError:
print("Invalid value")
Raising Strings Instead of Exception Instances
Some new Python programmers attempt to raise strings or plain messages instead of actual exception objects. This results in a TypeError
because Python only accepts
instances of BaseException
or its subclasses in raise
. Raising anything else is invalid syntax.
# Wrong
raise "Something went wrong" # Invalid
# Correct
raise RuntimeError("Something went wrong")
Ignoring Exception Messages
Another common issue is not reading or printing the error message from the caught exception. Python exceptions contain detailed messages that help you understand what exactly
went wrong. If you just write except:
without using the exception object, you lose valuable debugging information.
# Weak
try:
open("missing.txt")
except FileNotFoundError:
print("Error") # Not helpful
# Better
try:
open("missing.txt")
except FileNotFoundError as e:
print("Error:", e)
Using raise
Without a Message
Raising exceptions without a message leads to unclear and hard-to-debug code. While technically allowed, doing so means anyone reading the traceback gets no context about what went wrong. This becomes a big problem in larger programs or APIs.
# Not helpful
raise ValueError()
# Clear and informative
raise ValueError("Expected integer input, got string instead")
Always include descriptive messages when raising built-in exceptions to improve clarity.
Frequently Asked Questions
What are built-in exceptions in Python and why are they important?
Built-in exceptions in Python are predefined error types that the interpreter raises when something goes wrong during program execution. They include common issues such as
invalid values (ValueError
), type mismatches (TypeError
), division by zero (ZeroDivisionError
), and missing keys (KeyError
).
These exceptions help you understand exactly what caused a crash or bug.
They’re important because they provide structured, meaningful feedback when an error occurs. Instead of a vague or silent failure, Python raises a specific exception that you
can catch using try…except
blocks. This allows you to handle errors gracefully and write programs that fail safely, not silently.
Learning to work with built-in exceptions improves your debugging skills and helps you write more reliable, professional code. You should know how to raise them, catch them, and use them to guide program flow.
What is the difference between Exception
and BaseException
?
BaseException
is the root of all exceptions in Python, including system-level ones like SystemExit
, KeyboardInterrupt
, and
GeneratorExit
. Exception
is a subclass of BaseException
and is intended to be the base for all user-defined and built-in runtime errors.
In practice, you should almost always catch Exception
, not BaseException
. Catching BaseException
will also capture system signals that
should usually be allowed to propagate, such as keyboard interrupts. This can make your program harder to stop or debug.
So, use BaseException
only when you really need to catch absolutely everything — for example, in logging tools or low-level frameworks. For normal error handling,
stick to Exception
or more specific subclasses.
How do I know which built-in exception to use when raising an error?
Choosing the right built-in exception depends on the context of your error. Start by asking: What kind of problem has occurred? If it's related to an invalid value passed to a
function, use ValueError
. If the type is wrong, go with TypeError
. If an index is out of range, use IndexError
. Python’s built-in
exception names are very descriptive and usually match common error scenarios.
You can refer to the official Python documentation for a full list of exception types and their use cases. It’s better to use a specific exception whenever possible — it makes your error messages clearer and helps other developers understand what’s going on.
Using the correct exception also allows your code to integrate better with other tools, such as linters, loggers, and testing frameworks.
Can I raise built-in exceptions manually in my code?
Yes, you can raise any built-in exception manually using the raise
keyword. This is useful when you want to validate input, enforce rules, or prevent invalid
operations from continuing. For example, if you expect a positive number and receive a negative one, you might raise a ValueError
to signal the problem.
Manual raising of exceptions helps keep your code safe and predictable. It stops execution when conditions are not met and allows you to control how and where the program fails. This approach is common in defensive programming and API development.
Example:
def set_price(price):
if price < 0:
raise ValueError("Price cannot be negative")
This kind of proactive error handling is considered a good practice in Python development.