> ## Documentation Index
> Fetch the complete documentation index at: https://fastapi.codewithsiva.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Exception Handling

> Catch errors using try-except blocks, raise exceptions, and define custom exception classes

## 1. Try, Except, Else, and Finally

Python handles runtime errors using exception blocks. This prevents the application from crashing when an error occurs.

### The Basic Try-Except

The `try` block contains the code that might fail, while the `except` block catches specific error types and runs recovery logic.

```python theme={null}
try:
    number = int("not-a-number")
except ValueError:
    print("Please enter a valid integer")
```

### Multiple Error Types

You can catch different errors and handle them differently:

```python theme={null}
try:
    with open('number.txt', 'r') as f:
        text = f.read()
    number = int(text)
    result = 100 / number
except FileNotFoundError:
    print("Could not find the file")
except ValueError:
    print("File does not contain a valid number")
except ZeroDivisionError:
    print("Cannot divide by zero")
```

### Else and Finally

* **`else`**: Runs only if no exceptions were raised in the `try` block.
* **`finally`**: Always runs, regardless of whether an exception occurred or was handled. This block is typically used for clean-up tasks (like closing files or database connections).

```python theme={null}
try:
    file = open('data.txt', 'r')
    data = file.read()
except FileNotFoundError:
    print("File not found")
else:
    print("File loaded successfully")
finally:
    if 'file' in locals() and not file.closed:
        file.close()
    print("Cleanup complete")
```

***

## 2. Raising Exceptions

Use the `raise` keyword to manually trigger a built-in or custom exception when a business logic rule is violated.

```python theme={null}
def check_age(age: int):
    if age < 0:
        raise ValueError("Age cannot be negative!")
    if age < 18:
        raise ValueError("Must be at least 18 years old")
```

***

## 3. Custom Exception Classes

For larger applications, Python's built-in exceptions might not be descriptive enough. You can define domain-specific exceptions by inheriting from Python's base `Exception` class.

### Defining and Using Custom Exceptions

By convention, name your custom exceptions with the `Error` suffix.

```python theme={null}
# 1. Inherit from the base Exception class
class InsufficientBalanceError(Exception):
    """Raised when a withdrawal amount exceeds the account balance."""
    def __init__(self, balance: float, amount: float):
        self.balance = balance
        self.amount = amount
        super().__init__(f"Attempted to withdraw ${amount} but only have ${balance}")

# 2. Raise the custom exception in business logic
class BankAccount:
    def __init__(self, balance: float):
        self.balance = balance

    def withdraw(self, amount: float):
        if amount > self.balance:
            raise InsufficientBalanceError(self.balance, amount)
        self.balance -= amount
        print(f"Successfully withdrew ${amount}")

# 3. Catch the custom exception
account = BankAccount(100)
try:
    account.withdraw(150)
except InsufficientBalanceError as error:
    print(f"Transaction Failed: {error}")
    print(f"Shortage Amount: ${error.amount - error.balance}")
```

***

## Practice & Exercises

To reinforce what you've learned in this section (try-except blocks, handling multiple errors, else/finally blocks, raising exceptions, and writing custom exceptions), practice with these interactive notebooks:

<CardGroup cols={2}>
  <Card title="Follow-Along Practice" icon="laptop-code">
    Practice catching value errors, handling multiple exceptions like division by zero or file missing, using else and finally, raising validation errors, and subclassing Exception.

    [💻 VS Code](vscode://file/Users/sivaprasad/Downloads/python%20material/fastapi-course/public/notebooks/basics_exercises/Exception_Handling_Practice.ipynb) | [🚀 Colab](https://colab.research.google.com/github/prasad230776/fastapi-course/blob/master/public/notebooks/basics_exercises/Exception_Handling_Practice.ipynb) | <a href="/public/notebooks/basics_exercises/Exception_Handling_Practice.ipynb" download>📥 Download</a>
  </Card>

  <Card title="Practice Exercises" icon="pen-to-square">
    Test your knowledge with hands-on exercises including safe division function, config file loader cleanups, input username verifications, and custom email domain exceptions.

    [💻 VS Code](vscode://file/Users/sivaprasad/Downloads/python%20material/fastapi-course/public/notebooks/basics_exercises/Exception_Handling_Exercises.ipynb) | [🚀 Colab](https://colab.research.google.com/github/prasad230776/fastapi-course/blob/master/public/notebooks/basics_exercises/Exception_Handling_Exercises.ipynb) | <a href="/public/notebooks/basics_exercises/Exception_Handling_Exercises.ipynb" download>📥 Download</a>
  </Card>
</CardGroup>
