Back When to raise Which Error : Basics But Important 05 Feb, 2026

Understanding when to raise which error is a senior-level programming skill — especially important for clean architecture, APIs, ETL pipelines, and LLM systems like the ones you are building.

I’ll explain this in a very intuitive, real-life, and practical way, with:

  • 🧠 mental models

  • 🚦 when to raise which error

  • 🧪 real code examples

  • 📦 common errors you actually encounter in day-to-day programming


🧠 First: What does “raise an error” really mean?

Raising an error is like stopping the program at the exact point where something becomes invalid.

Think of it as:

❌ “I refuse to continue because something is fundamentally wrong.”

Errors are not failures — they are guards 🛡️.


🏠 Real-Life Analogy

SituationEquivalent Error
Wrong PIN in ATMValueError
Electricity not availableEnvironmentError
Door lockedPermissionError
Asking for 6th floor in 5-floor buildingIndexError
Calling a person who doesn’t existAttributeError

1️⃣ ValueError – ❌ Wrong Value (Most Common)

🔍 When to raise ValueError

Raise ValueError when:

  • Type is correct ✅

  • But value is logically invalid

🧠 Mental Model

“I understand your input, but its value doesn’t make sense.”


✅ Examples

Age validation

def set_age(age):
    if age <= 0:
        raise ValueError("Age must be positive")

age is an int
❌ but -5 is invalid


Config value invalid

if chunk_size <= 0:
    raise ValueError("chunk_size must be greater than 0")

🔥 Very common cases

  • Invalid thresholds

  • Empty strings where not allowed

  • Invalid enum values

  • Out-of-range numbers


2️⃣ TypeError – ❌ Wrong Type

🔍 When to raise TypeError

Raise when:

  • Type itself is wrong

  • Operation cannot proceed

🧠 Mental Model

“I don’t even understand what you gave me.”


Example

def calculate_discount(price):
    if not isinstance(price, (int, float)):
        raise TypeError("Price must be a number")

🔥 Typical scenarios

  • String instead of number

  • List instead of dict

  • None where object expected


3️⃣ EnvironmentError / OSError – 🌍 System / Environment Problem

⚠️ In modern Python, EnvironmentError is an alias of OSError

🔍 When to raise

Raise when:

  • Problem is outside your code

  • OS, environment variables, file system, network

🧠 Mental Model

“Your system environment is not ready.”


Example: Missing environment variable

if os.getenv("GOOGLE_API_KEY") is None:
    raise EnvironmentError("GOOGLE_API_KEY not set")

Other cases

  • File not found

  • Disk full

  • Permission denied

  • Network unavailable


4️⃣ FileNotFoundError – 📄 File Missing

Subclass of OSError

When to raise

if not os.path.exists(file_path):
    raise FileNotFoundError(f"{file_path} not found")

Use when:

  • File is mandatory

  • Cannot continue without it


5️⃣ PermissionError – 🔒 No Access

Mental model

“The file exists, but you’re not allowed.”

if not os.access(path, os.R_OK):
    raise PermissionError("Read permission denied")

6️⃣ KeyError – 🔑 Missing Dictionary Key

When to raise

if "llm" not in config:
    raise KeyError("Missing 'llm' section in config")

Common in:

  • JSON configs

  • API responses

  • YAML files


7️⃣ IndexError – 📦 Out of Range

When to raise

if index >= len(items):
    raise IndexError("Index out of range")

Typical cases

  • Lists

  • Tuples

  • Pagination logic


8️⃣ AttributeError – 🧩 Missing Attribute

Mental model

“This object doesn’t have what you’re asking for.”

if not hasattr(obj, "embed_query"):
    raise AttributeError("Embedding model missing embed_query()")

🔥 You’ve already faced this in LangChain imports 😉


9️⃣ RuntimeError – ⚙️ Program State is Wrong

When to raise

  • Logic error

  • State inconsistency

  • Should never happen normally

if self.vectorstore is None:
    raise RuntimeError("Vector store not initialized")

🔟 NotImplementedError – 🚧 Feature Placeholder

When to raise

def load_llm(self):
    raise NotImplementedError("LLM provider not implemented yet")

Used in:

  • Abstract classes

  • Base interfaces


1️⃣1️⃣ TimeoutError – ⏳ Operation Took Too Long

raise TimeoutError("Request to API timed out")

Used in:

  • APIs

  • Web scraping

  • LLM calls


1️⃣2️⃣ Custom Exceptions – 🧑‍🎨 Best Practice

For production systems, create your own errors.

Example

class ConfigurationError(Exception):
    pass

if "embedding" not in config:
    raise ConfigurationError("Embedding config missing")

✔ Cleaner logs
✔ Better debugging
✔ Better error handling


🧠 Decision Table (Cheat Sheet)

SituationRaise
Wrong valueValueError
Wrong typeTypeError
Missing env variableEnvironmentError
File missingFileNotFoundError
No permissionPermissionError
Missing dict keyKeyError
Index out of rangeIndexError
Missing object methodAttributeError
Bad app stateRuntimeError
Feature not builtNotImplementedError

🎯 How YOU should use this (Based on projects)

For your:

  • 🔗 LangChain pipelines

  • 🛒 Scrapers

  • 🧠 LLM loaders

  • ⚙️ ETL systems

👉 Always:

  1. Validate early

  2. Raise specific errors

  3. Never silently fail

  4. Log before raising (production)