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 using try…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.