# Code Smell 288 - Unthrown Exceptions

> TL;DR: Creating a new exception without throwing it leads to silent failures. 👃💩

# Problems 😔

- **Silent** failures
- Unhandled errors
- Misleading logic
- Hidden defects
- Hollow [Exceptions](https://maximilianocontieri.com/code-smell-26-exceptions-polluting)

# Solutions 😃

1. Always ensure you **throw exceptions**
2. Check exception usage and catching
3. Test exception paths
4. Use **linters**
5. Avoid creating [unused exceptions](https://maximilianocontieri.com/code-smell-26-exceptions-polluting)

# Context 💬

When you create a new exception but **forget to throw it**, your code might appear to work correctly, but it **silently** ignores critical errors.

Creating exceptions is the same as creating business objects and constructors should not have [**side effects**](https://maximilianocontieri.com/code-smell-142-queries-in-constructors).

Unless you throw them, it is **[dead code](https://maximilianocontieri.com/code-smell-09-dead-code)**.

# Sample Code

## Wrong 🚫

<!-- [Gist Url](https://gist.github.com/mcsee/245571d7abd11ef733f02b850be470af) -->

```python
class KlendathuInvasionError(Exception):
    def __init__(self, message):
        self.message = message
    # This is a hollow exception        

def deploy_troops(safe):
    if not safe:
        KlendathuInvasionError("Drop zone is hot!")  
        # Never thrown
    print("Troopers deployed.")

deploy_troops(False)
```

## Right 👉

<!-- [Gist Url](https://gist.github.com/mcsee/8594a2641887d973c8b7b397d1facdab) -->

```python
class KlendathuInvasionError(Exception):
    def __init__(self, message):
        super().__init__(message)

def deploy_troops(safe):
    if not safe:
        raise Exception("Drop zone is hot!")
    # You throw the exception
    print("Troopers deployed.")

try:
    deploy_troops(False)
except KlendathuInvasionError as e:
    print(f"Abort mission: {e}")
    # You handle the exception
```

# Detection 🔍

You can detect this smell by reviewing your code for instances where you create exceptions but do not raise them.

You can also search for instances where an exception is instantiated but never raised.

Automated linters and static analyzers can flag such issues.

# Tags 🏷️

- Exceptions

# Level 🔋

[X] Beginner

# Why the Bijection Is Important

An exception represents a real-world [failure](https://maximilianocontieri.com/code-smell-73-exceptions-for-expected-cases) inside your program.

If you create an exception but never throw it, your code lies about the presence of an error.

When you fail to throw an exception, you break the [one-to-one](https://maximilianocontieri.com/what-is-wrong-with-software) correspondence between the real-world problem and its coding representation.

# AI Generation 🤖

AI generators might create this smell if they generate exception-handling code without **ensuring that exceptions are properly raised**.

Always review AI-generated code for proper error handling.

# AI Detection 🦾

AI-based linters can detect this smell by analyzing unreferenced exception instances.

Fixing it requires proper domain knowledge to decide **where to throw the exception**.

## Try Them! 🛞

*Remember: AI Assistants make lots of mistakes*

| Without Proper Instructions    | With Specific Instructions |
| -------- | ------- |
| [ChatGPT](https://chat.openai.com/?q=Correct+and+explain+this+code%3A+%60%60%60python%0D%0Aclass+KlendathuInvasionError%28Exception%29%3A%0D%0A++++def+__init__%28self%2C+message%29%3A%0D%0A++++++++self.message+%3D+message%0D%0A++++%23+This+is+a+hollow+exception++++++++%0D%0A%0D%0Adef+deploy_troops%28safe%29%3A%0D%0A++++if+not+safe%3A%0D%0A++++++++KlendathuInvasionError%28%22Drop+zone+is+hot%21%22%29++%0D%0A++++++++%23+Never+thrown%0D%0A++++print%28%22Troopers+deployed.%22%29%0D%0A%0D%0Adeploy_troops%28False%29%0D%0A%60%60%60) | [ChatGPT](https://chat.openai.com/?q=make+sure+the+exception+was+thrown%3A+%60%60%60python%0D%0Aclass+KlendathuInvasionError%28Exception%29%3A%0D%0A++++def+__init__%28self%2C+message%29%3A%0D%0A++++++++self.message+%3D+message%0D%0A++++%23+This+is+a+hollow+exception++++++++%0D%0A%0D%0Adef+deploy_troops%28safe%29%3A%0D%0A++++if+not+safe%3A%0D%0A++++++++KlendathuInvasionError%28%22Drop+zone+is+hot%21%22%29++%0D%0A++++++++%23+Never+thrown%0D%0A++++print%28%22Troopers+deployed.%22%29%0D%0A%0D%0Adeploy_troops%28False%29%0D%0A%60%60%60) |
| [Claude](https://claude.ai/new?q=Correct+and+explain+this+code%3A+%60%60%60python%0D%0Aclass+KlendathuInvasionError%28Exception%29%3A%0D%0A++++def+__init__%28self%2C+message%29%3A%0D%0A++++++++self.message+%3D+message%0D%0A++++%23+This+is+a+hollow+exception++++++++%0D%0A%0D%0Adef+deploy_troops%28safe%29%3A%0D%0A++++if+not+safe%3A%0D%0A++++++++KlendathuInvasionError%28%22Drop+zone+is+hot%21%22%29++%0D%0A++++++++%23+Never+thrown%0D%0A++++print%28%22Troopers+deployed.%22%29%0D%0A%0D%0Adeploy_troops%28False%29%0D%0A%60%60%60) | [Claude](https://claude.ai/new?q=make+sure+the+exception+was+thrown%3A+%60%60%60python%0D%0Aclass+KlendathuInvasionError%28Exception%29%3A%0D%0A++++def+__init__%28self%2C+message%29%3A%0D%0A++++++++self.message+%3D+message%0D%0A++++%23+This+is+a+hollow+exception++++++++%0D%0A%0D%0Adef+deploy_troops%28safe%29%3A%0D%0A++++if+not+safe%3A%0D%0A++++++++KlendathuInvasionError%28%22Drop+zone+is+hot%21%22%29++%0D%0A++++++++%23+Never+thrown%0D%0A++++print%28%22Troopers+deployed.%22%29%0D%0A%0D%0Adeploy_troops%28False%29%0D%0A%60%60%60) |
| [Perplexity](https://perplexity.ai/?q=Correct+and+explain+this+code%3A+%60%60%60python%0D%0Aclass+KlendathuInvasionError%28Exception%29%3A%0D%0A++++def+__init__%28self%2C+message%29%3A%0D%0A++++++++self.message+%3D+message%0D%0A++++%23+This+is+a+hollow+exception++++++++%0D%0A%0D%0Adef+deploy_troops%28safe%29%3A%0D%0A++++if+not+safe%3A%0D%0A++++++++KlendathuInvasionError%28%22Drop+zone+is+hot%21%22%29++%0D%0A++++++++%23+Never+thrown%0D%0A++++print%28%22Troopers+deployed.%22%29%0D%0A%0D%0Adeploy_troops%28False%29%0D%0A%60%60%60) | [Perplexity](https://perplexity.ai/?q=make+sure+the+exception+was+thrown%3A+%60%60%60python%0D%0Aclass+KlendathuInvasionError%28Exception%29%3A%0D%0A++++def+__init__%28self%2C+message%29%3A%0D%0A++++++++self.message+%3D+message%0D%0A++++%23+This+is+a+hollow+exception++++++++%0D%0A%0D%0Adef+deploy_troops%28safe%29%3A%0D%0A++++if+not+safe%3A%0D%0A++++++++KlendathuInvasionError%28%22Drop+zone+is+hot%21%22%29++%0D%0A++++++++%23+Never+thrown%0D%0A++++print%28%22Troopers+deployed.%22%29%0D%0A%0D%0Adeploy_troops%28False%29%0D%0A%60%60%60) |
| [Copilot](https://www.bing.com/chat?showconv=1&sendquery=1&q=Correct+and+explain+this+code%3A+%60%60%60python%0D%0Aclass+KlendathuInvasionError%28Exception%29%3A%0D%0A++++def+__init__%28self%2C+message%29%3A%0D%0A++++++++self.message+%3D+message%0D%0A++++%23+This+is+a+hollow+exception++++++++%0D%0A%0D%0Adef+deploy_troops%28safe%29%3A%0D%0A++++if+not+safe%3A%0D%0A++++++++KlendathuInvasionError%28%22Drop+zone+is+hot%21%22%29++%0D%0A++++++++%23+Never+thrown%0D%0A++++print%28%22Troopers+deployed.%22%29%0D%0A%0D%0Adeploy_troops%28False%29%0D%0A%60%60%60) | [Copilot](https://www.bing.com/chat?showconv=1&sendquery=1&q=make+sure+the+exception+was+thrown%3A+%60%60%60python%0D%0Aclass+KlendathuInvasionError%28Exception%29%3A%0D%0A++++def+__init__%28self%2C+message%29%3A%0D%0A++++++++self.message+%3D+message%0D%0A++++%23+This+is+a+hollow+exception++++++++%0D%0A%0D%0Adef+deploy_troops%28safe%29%3A%0D%0A++++if+not+safe%3A%0D%0A++++++++KlendathuInvasionError%28%22Drop+zone+is+hot%21%22%29++%0D%0A++++++++%23+Never+thrown%0D%0A++++print%28%22Troopers+deployed.%22%29%0D%0A%0D%0Adeploy_troops%28False%29%0D%0A%60%60%60) |
| [Gemini](https://gemini.google.com/?q=Correct+and+explain+this+code%3A+%60%60%60python%0D%0Aclass+KlendathuInvasionError%28Exception%29%3A%0D%0A++++def+__init__%28self%2C+message%29%3A%0D%0A++++++++self.message+%3D+message%0D%0A++++%23+This+is+a+hollow+exception++++++++%0D%0A%0D%0Adef+deploy_troops%28safe%29%3A%0D%0A++++if+not+safe%3A%0D%0A++++++++KlendathuInvasionError%28%22Drop+zone+is+hot%21%22%29++%0D%0A++++++++%23+Never+thrown%0D%0A++++print%28%22Troopers+deployed.%22%29%0D%0A%0D%0Adeploy_troops%28False%29%0D%0A%60%60%60) | [Gemini](https://gemini.google.com/?q=make+sure+the+exception+was+thrown%3A+%60%60%60python%0D%0Aclass+KlendathuInvasionError%28Exception%29%3A%0D%0A++++def+__init__%28self%2C+message%29%3A%0D%0A++++++++self.message+%3D+message%0D%0A++++%23+This+is+a+hollow+exception++++++++%0D%0A%0D%0Adef+deploy_troops%28safe%29%3A%0D%0A++++if+not+safe%3A%0D%0A++++++++KlendathuInvasionError%28%22Drop+zone+is+hot%21%22%29++%0D%0A++++++++%23+Never+thrown%0D%0A++++print%28%22Troopers+deployed.%22%29%0D%0A%0D%0Adeploy_troops%28False%29%0D%0A%60%60%60) | 
| [DeepSeek](https://chat.deepseek.com/?q=Correct+and+explain+this+code%3A+%60%60%60python%0D%0Aclass+KlendathuInvasionError%28Exception%29%3A%0D%0A++++def+__init__%28self%2C+message%29%3A%0D%0A++++++++self.message+%3D+message%0D%0A++++%23+This+is+a+hollow+exception++++++++%0D%0A%0D%0Adef+deploy_troops%28safe%29%3A%0D%0A++++if+not+safe%3A%0D%0A++++++++KlendathuInvasionError%28%22Drop+zone+is+hot%21%22%29++%0D%0A++++++++%23+Never+thrown%0D%0A++++print%28%22Troopers+deployed.%22%29%0D%0A%0D%0Adeploy_troops%28False%29%0D%0A%60%60%60) | [DeepSeek](https://chat.deepseek.com/?q=make+sure+the+exception+was+thrown%3A+%60%60%60python%0D%0Aclass+KlendathuInvasionError%28Exception%29%3A%0D%0A++++def+__init__%28self%2C+message%29%3A%0D%0A++++++++self.message+%3D+message%0D%0A++++%23+This+is+a+hollow+exception++++++++%0D%0A%0D%0Adef+deploy_troops%28safe%29%3A%0D%0A++++if+not+safe%3A%0D%0A++++++++KlendathuInvasionError%28%22Drop+zone+is+hot%21%22%29++%0D%0A++++++++%23+Never+thrown%0D%0A++++print%28%22Troopers+deployed.%22%29%0D%0A%0D%0Adeploy_troops%28False%29%0D%0A%60%60%60) | 
| [Meta AI](https://www.meta.ai/chat?question=Correct+and+explain+this+code%3A+%60%60%60python%0D%0Aclass+KlendathuInvasionError%28Exception%29%3A%0D%0A++++def+__init__%28self%2C+message%29%3A%0D%0A++++++++self.message+%3D+message%0D%0A++++%23+This+is+a+hollow+exception++++++++%0D%0A%0D%0Adef+deploy_troops%28safe%29%3A%0D%0A++++if+not+safe%3A%0D%0A++++++++KlendathuInvasionError%28%22Drop+zone+is+hot%21%22%29++%0D%0A++++++++%23+Never+thrown%0D%0A++++print%28%22Troopers+deployed.%22%29%0D%0A%0D%0Adeploy_troops%28False%29%0D%0A%60%60%60) | [Meta AI](https://www.meta.ai/chat?question=make+sure+the+exception+was+thrown%3A+%60%60%60python%0D%0Aclass+KlendathuInvasionError%28Exception%29%3A%0D%0A++++def+__init__%28self%2C+message%29%3A%0D%0A++++++++self.message+%3D+message%0D%0A++++%23+This+is+a+hollow+exception++++++++%0D%0A%0D%0Adef+deploy_troops%28safe%29%3A%0D%0A++++if+not+safe%3A%0D%0A++++++++KlendathuInvasionError%28%22Drop+zone+is+hot%21%22%29++%0D%0A++++++++%23+Never+thrown%0D%0A++++print%28%22Troopers+deployed.%22%29%0D%0A%0D%0Adeploy_troops%28False%29%0D%0A%60%60%60) | 

# Conclusion ✔️

Always throw exceptions **immediately** after you create them.

Silent failures can lead to significant issues in your code, making it harder to maintain and debug.

Proper error handling and **good coverage** ensure your code behaves predictably and reliably.

# Relations 👩‍❤️‍💋‍👨

%[https://maximilianocontieri.com/code-smell-165-empty-exception-blocks]

%[https://maximilianocontieri.com/code-smell-26-exceptions-polluting]

%[https://maximilianocontieri.com/code-smell-142-queries-in-constructors]

%[https://maximilianocontieri.com/code-smell-09-dead-code]

%[https://maximilianocontieri.com/code-smell-132-exception-try-too-broad]

%[https://maximilianocontieri.com/code-smell-73-exceptions-for-expected-cases]

# Disclaimer 📘

Code Smells are my [opinion](https://maximilianocontieri.com/i-wrote-more-than-90-articles-on-2021-here-is-what-i-learned).

# Credits 🙏

Photo by [Bethany Reeves](https://unsplash.com/@bethanyreeeves) on [Unsplash](https://unsplash.com/photos/a-rusted-boat-sitting-on-top-of-a-rocky-beach-pRJ3Unwsnjw)

* * *

> Software is like entropy: It is difficult to grasp, weighs nothing, and obeys the Second Law of Thermodynamics; i.e., it always increases.

_Norman Augustine_

%[https://maximilianocontieri.com/software-engineering-great-quotes]

* * *

This article is part of the CodeSmell Series.

%[https://maximilianocontieri.com/how-to-find-the-stinky-parts-of-your-code]
