The answer to your question is you want meaningful exceptions.

In most contexts, this involves an exception that adds actionable information in one of two ways:

  • Useful typing to the developer who might be catching the exception
  • Useful error information to the user (and/or to the developer who can translate to that the user)

In your example, you aren't really adding anything to the normal exception. Catching and then effectively reraising the exception isn't useful. You could log this information, in which case you now added some value to the exception, but otherwise it's pointless.

Imagine this scenario:

try:
   my_web_function()
except my_custom_web_exception:
   do_something_with_this_exception()

It's entirely reasonable to imagine this scenario. You might make an http request. Most libraries have defined exception types, so you could catch those exceptions, and if it happens, do something.

The "something" is dependent on the specific application. In a http exception, maybe it's just retry the request. Etc.

But the point is catching the exception adds value and information and is actionable.

Answer from enderland on Stack Exchange
🌐
Python documentation
docs.python.org › 3 › tutorial › errors.html
8. Errors and Exceptions — Python 3.14.3 documentation
The variable is bound to the exception instance which typically has an args attribute that stores the arguments. For convenience, builtin exception types define __str__() to print all the arguments without explicitly accessing .args. >>> try: ... raise Exception('spam', 'eggs') ...
🌐
W3Schools
w3schools.com › python › gloss_python_raise.asp
Python Raise an Exception
As a Python developer you can choose to throw an exception if a condition occurs. To throw (or raise) an exception, use the raise keyword.
Discussions

Why raise an exception if python raises it for me? - Software Engineering Stack Exchange
I have a global position keeper of screen items so items don't need store their own positions. class Screen_Position_Keeper: # functions to add stuff def get_px_row( self, item ): ... More on softwareengineering.stackexchange.com
🌐 softwareengineering.stackexchange.com
September 25, 2016
Manually raising (throwing) an exception in Python - Stack Overflow
How do I raise an exception in Python so that it can later be caught via an except block? More on stackoverflow.com
🌐 stackoverflow.com
"raise" at the end of a python function outside "try" or "except" block - Stack Overflow
What does raise do, if it's not inside a try or except clause, but simply as the last statement in the function? def foo(self): try: # some code that raises an exception except Exc... More on stackoverflow.com
🌐 stackoverflow.com
Explain the term “raise an exception” without using the terms “raise” or “throw”
Try reading about excepting handling in python with some example code, this should help you understand. https://www.programiz.com/python-programming/exception-handling TL;DR; sequential execution is stopped when an exception happens, and it looks for an except: block to handle it, and starts executing a matching except block. If no such block found anywhere, including above functions etc, it is finally shown as an error to the user stopping the entire code. More on reddit.com
🌐 r/learnpython
11
0
February 23, 2022
🌐
Python
peps.python.org › pep-0008
PEP 8 – Style Guide for Python Code | peps.python.org
Use exception chaining appropriately. raise X from Y should be used to indicate explicit replacement without losing the original traceback.
🌐
Luis Llamas
luisllamas.es › inicio › cursos › curso python
Raising Exceptions with `raise` in Python
November 20, 2024 - By using raise, we can generate custom errors or re-raise caught exceptions to be handled at a higher level of the program. The raise statement in Python is used to intentionally raise an exception.
🌐
Real Python
realpython.com › python-exceptions
Python Exceptions: An Introduction – Real Python
December 1, 2024 - In this beginner tutorial, you'll learn what exceptions are good for in Python. You'll see how to raise exceptions and how to handle them with try ... except blocks.
Top answer
1 of 4
6

The answer to your question is you want meaningful exceptions.

In most contexts, this involves an exception that adds actionable information in one of two ways:

  • Useful typing to the developer who might be catching the exception
  • Useful error information to the user (and/or to the developer who can translate to that the user)

In your example, you aren't really adding anything to the normal exception. Catching and then effectively reraising the exception isn't useful. You could log this information, in which case you now added some value to the exception, but otherwise it's pointless.

Imagine this scenario:

try:
   my_web_function()
except my_custom_web_exception:
   do_something_with_this_exception()

It's entirely reasonable to imagine this scenario. You might make an http request. Most libraries have defined exception types, so you could catch those exceptions, and if it happens, do something.

The "something" is dependent on the specific application. In a http exception, maybe it's just retry the request. Etc.

But the point is catching the exception adds value and information and is actionable.

2 of 4
3

An error I encountered late last week wasn't due to a python script, but the same principle applies. I had the "privilege" of having to use an old version of subversion on a project. I mistakenly mistyped

prompt: svn co https://some.site.com/some/path

The system's response was

svn: OPTIONS of 'https://some.site.com/some/path': 200 OK (https://some.site.com)

This message was not only unhelpful, it was incorrect. (Giving someone an HTTP/HTTPS "200 OK" status when what happened was far from okay is not OK.) Moreover, there are multiple pathways in subversion 1.9 that result in that erroneous "200 OK" error message. A much more helpful message would have been to tell me that I had mistyped the repository's URL.

Strictly speaking, this was not a bug in subversion. It was just a poorly worded error message. After all, subversion did properly detect and report the problem. From a user perspective, this was a huge bug that was mostly fixed in 2010. Thankfully, a quick google search resulted in multiple hits at stackoverflow.com.


Programmers are often taught that they should simply let an exception pass through if they can't do something about it. Instructors as well as students think "doing something" means correcting the problem. In many cases, there is nothing that can be done to correct a problem. This is an overly narrow view of "doing something." Adding context that enables a user to hone in on the problem and then fix it is "doing something."

Another way of looking at letting low level exceptions bubble up is that doing so is a leaky abstraction.

Find elsewhere
🌐
Python Software Foundation
wiki.python.org › python › HandlingExceptions.html
HandlingExceptions
February 14, 2026 - However, as of Python 3, exceptions must subclass BaseException. -- ElephantJim ... You know- you can put a print d in there, and that works. But is there a better, more interesting way to get at that information that people know of? ... The .args attribute of exceptions is a tuple of all the arguments that were passed in (typically the one and only argument is the error message). This way you can modify the arguments and re-raise, and the extra information will be displayed.
🌐
DEV Community
dev.to › kfir-g › raising-the-difference-between-raise-and-raise-e-378h
Raising the Difference Between raise and raise e - DEV Community
November 16, 2024 - raise e: Re-raises the caught exception but resets the traceback to start from the line where raise e is called. The distinction may seem minor, but it can significantly impact how tracebacks are displayed and how easy they are to interpret.
🌐
QuantInsti
blog.quantinsti.com › python-exception
Python Exception: Raising And Catching Exceptions In Python
July 12, 2019 - In this example, we call simple_div(2, a) function with one number and a variable named a, hence the function doesn’t work because the variable is not initialized, therefore, Python raises an exception (a python exception) called in this case NameError, the execution ends abruptly and does not let us continue.
Top answer
1 of 11
4324

How do I manually throw/raise an exception in Python?

Use the most specific Exception constructor that semantically fits your issue.

Be specific in your message, e.g.:

raise ValueError('A very specific bad thing happened.')

Don't raise generic exceptions

Avoid raising a generic Exception. To catch it, you'll have to catch all other more specific exceptions that subclass it.

Problem 1: Hiding bugs

raise Exception('I know Python!') # Don't! If you catch, likely to hide bugs.

For example:

def demo_bad_catch():
    try:
        raise ValueError('Represents a hidden bug, do not catch this')
        raise Exception('This is the exception you expect to handle')
    except Exception as error:
        print('Caught this error: ' + repr(error))

>>> demo_bad_catch()
Caught this error: ValueError('Represents a hidden bug, do not catch this',)

Problem 2: Won't catch

And more specific catches won't catch the general exception:

def demo_no_catch():
    try:
        raise Exception('general exceptions not caught by specific handling')
    except ValueError as e:
        print('we will not catch exception: Exception')
 

>>> demo_no_catch()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in demo_no_catch
Exception: general exceptions not caught by specific handling

Best Practices: raise statement

Instead, use the most specific Exception constructor that semantically fits your issue.

raise ValueError('A very specific bad thing happened')

which also handily allows an arbitrary number of arguments to be passed to the constructor:

raise ValueError('A very specific bad thing happened', 'foo', 'bar', 'baz') 

These arguments are accessed by the args attribute on the Exception object. For example:

try:
    some_code_that_may_raise_our_value_error()
except ValueError as err:
    print(err.args)

prints

('message', 'foo', 'bar', 'baz')    

In Python 2.5, an actual message attribute was added to BaseException in favor of encouraging users to subclass Exceptions and stop using args, but the introduction of message and the original deprecation of args has been retracted.

Best Practices: except clause

When inside an except clause, you might want to, for example, log that a specific type of error happened, and then re-raise. The best way to do this while preserving the stack trace is to use a bare raise statement. For example:

logger = logging.getLogger(__name__)

try:
    do_something_in_app_that_breaks_easily()
except AppError as error:
    logger.error(error)
    raise                 # just this!
    # raise AppError      # Don't do this, you'll lose the stack trace!

Don't modify your errors... but if you insist.

You can preserve the stacktrace (and error value) with sys.exc_info(), but this is way more error prone and has compatibility problems between Python 2 and 3, prefer to use a bare raise to re-raise.

To explain - the sys.exc_info() returns the type, value, and traceback.

type, value, traceback = sys.exc_info()

This is the syntax in Python 2 - note this is not compatible with Python 3:

raise AppError, error, sys.exc_info()[2] # avoid this.
# Equivalently, as error *is* the second object:
raise sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]

If you want to, you can modify what happens with your new raise - e.g. setting new args for the instance:

def error():
    raise ValueError('oops!')

def catch_error_modify_message():
    try:
        error()
    except ValueError:
        error_type, error_instance, traceback = sys.exc_info()
        error_instance.args = (error_instance.args[0] + ' <modification>',)
        raise error_type, error_instance, traceback

And we have preserved the whole traceback while modifying the args. Note that this is not a best practice and it is invalid syntax in Python 3 (making keeping compatibility much harder to work around).

>>> catch_error_modify_message()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in catch_error_modify_message
  File "<stdin>", line 2, in error
ValueError: oops! <modification>

In Python 3:

raise error.with_traceback(sys.exc_info()[2])

Again: avoid manually manipulating tracebacks. It's less efficient and more error prone. And if you're using threading and sys.exc_info you may even get the wrong traceback (especially if you're using exception handling for control flow - which I'd personally tend to avoid.)

Python 3, Exception chaining

In Python 3, you can chain Exceptions, which preserve tracebacks:

raise RuntimeError('specific message') from error

Be aware:

  • this does allow changing the error type raised, and
  • this is not compatible with Python 2.

Deprecated Methods:

These can easily hide and even get into production code. You want to raise an exception, and doing them will raise an exception, but not the one intended!

Valid in Python 2, but not in Python 3 is the following:

raise ValueError, 'message' # Don't do this, it's deprecated!

Only valid in much older versions of Python (2.4 and lower), you may still see people raising strings:

raise 'message' # really really wrong. don't do this.

In all modern versions, this will actually raise a TypeError, because you're not raising a BaseException type. If you're not checking for the right exception and don't have a reviewer that's aware of the issue, it could get into production.

Example Usage

I raise Exceptions to warn consumers of my API if they're using it incorrectly:

def api_func(foo):
    '''foo should be either 'baz' or 'bar'. returns something very useful.'''
    if foo not in _ALLOWED_ARGS:
        raise ValueError('{foo} wrong, use "baz" or "bar"'.format(foo=repr(foo)))

Create your own error types when apropos

"I want to make an error on purpose, so that it would go into the except"

You can create your own error types, if you want to indicate something specific is wrong with your application, just subclass the appropriate point in the exception hierarchy:

class MyAppLookupError(LookupError):
    '''raise this when there's a lookup error for my app'''

and usage:

if important_key not in resource_dict and not ok_to_be_missing:
    raise MyAppLookupError('resource is missing, and that is not ok.')
2 of 11
579

Don't do this. Raising a bare Exception is absolutely not the right thing to do; see Aaron Hall's excellent answer instead.

It can't get much more Pythonic than this:

raise Exception("I know Python!")

Replace Exception with the specific type of exception you want to throw.

See the raise statement documentation for Python if you'd like more information.

🌐
Medium
medium.com › @yash.patel. › the-art-of-raising-and-catching-exceptions-in-python-bc4d995c9ce2
The Art of Raising and Catching Exceptions in Python | by YashPatel | Medium
December 20, 2023 - At their core, exceptions are objects that provide information about errors or anomalous program conditions. When something abnormal occurs like a TypeError (example: TypeError: string indices must be integers) or ValueError (example: ValueError: could not convert string to float), Python raises an exception object and transfers control to the exception handler.
🌐
CodingNomads
codingnomads.com › python-raise-exception
Python Raise Exception
When the raise statement is used, the program leaves its path of execution and searches for the nearest try except block where the exception might be caught. If the raise is not contained inside of a try except block, then the raised exception ...
🌐
My Docs
codebay.ai › welcome to codebay › glossaries › error and exceptions › raise statements
raise Statements | Codebay
April 7, 2024 - The raise statement, in Python, allows the programmer to force a specified exception to occur.
🌐
Geek University
geek-university.com › home › raise exception
Raise exception | Python#
February 11, 2022 - You can use the raise keyword to signal that the situation is exceptional to the normal flow. For example: x = 5 if x < 10: raise ValueError('x should not be less than 10!') Notice how you can write the error message with more information inside ...
🌐
Reddit
reddit.com › r/learnpython › explain the term “raise an exception” without using the terms “raise” or “throw”
r/learnpython on Reddit: Explain the term “raise an exception” without using the terms “raise” or “throw”
February 23, 2022 -

I’m a python learner and am pretty ok with the syntax, and am now finding myself struggling with some of the deeper concepts, in this case error handling. Our environment is python running in a pytest framework using some pre-structured functions along with scripts and functions we write ourselves. I have visibility into the scripts and functions I write, along with some of the pre-structured functions, but the lowest level functions are beyond my view and control. I regularly run into exceptions in these lower levels and am trying to understand what’s going on. All the references I find say something like “raising an exception is when an executions error occurs, the error is raised as an exception”. This makes me nuts as they are explaining the term by using the term. So… Q1: what happens when an “exception is raised”? In terms of program execution and control and variables. Q2: if my script calls a function1 that calls a function2 which contains a command that “raises an exception” can I catch and handle it in function1 or in my top-level script, and if so, how? Q3: if I’m asking the wrong question, what should I be asking and/or researching?

Top answer
1 of 5
4
Try reading about excepting handling in python with some example code, this should help you understand. https://www.programiz.com/python-programming/exception-handling TL;DR; sequential execution is stopped when an exception happens, and it looks for an except: block to handle it, and starts executing a matching except block. If no such block found anywhere, including above functions etc, it is finally shown as an error to the user stopping the entire code.
2 of 5
4
So… Q1: what happens when an “exception is raised”? Go back a step - what happens when a function is called? Maybe you've got an idea, but let's be explicit - what happens is that the interpreter "puts a pin" in what it's currently doing, the line it's currently executing, and it jumps to the body of the function and executes that. Only it's not actually a pin, it's a stack frame. It puts a frame on the call stack - a collection of these frames, in the form of a stack, that the interpreter is using to keep track of where it needs to go back to when the function returns - and starts executing the body of the function that was called. If that function calls a function, then another frame goes on the call stack and you jump into the body of the new function. When the function returns, you "pop" a frame off the stack, and you return to where the function was called, possibly holding a return value. If you've written functions that call functions (that call functions, etc...) then you've had some intuitive notion of "returning" all the way back to where you started. That's called "unwinding the stack." When you raise an exception, somewhere deep in a nest of called functions, what the interpreter does is start removing stack frames from the stack, immediately returning functions wherever they're currently at in their execution. It keeps track as it does so, and you see that in the error output as something called the exception stacktrace: Traceback (most recent call last): File "/path/to/example.py", line 4, in greet('Chad') File "/path/to/example.py", line 2, in greet print('Hello, ' + someon) NameError: name 'someon' is not defined The interpreter pops stack frames until one of two things happens - either you pop all the way to an empty stack and your Python program exits with a relevant error code, or you pop into the body of a try block. If the try block is followed by an except block that declares it can handle errors of that type (so, except NameError to catch our example exception above) then the interpreter stops popping stack frames and moves execution to that except block and continues from there. That's what it means to raise an exception - it means "start to unwind the execution call stack of your program until the interpreter finds itself in a frame where the exception can be handled, or it runs out of frames."
🌐
Medium
medium.com › @andrewdass › python-errors-exceptions-and-the-raise-keyword-f5226ccbcf19
Python: Errors, Exceptions and the Raise Keyword | by Andrew Dass | Medium
April 1, 2025 - Exceptions (1) can be implemented ... and continue running the remainder of the Python script. An exception can also be triggered by using the “raise” keyword, which will also be demonstrated....
🌐
Tutorialspoint
tutorialspoint.com › python › python_raising_exceptions.htm
Python - Raising Exceptions
To re-raise an exception in Python, you use the "raise" statement without specifying an exception, which will re-raise the last exception that was active in the current scope.
🌐
Python
docs.python.org › 3 › library › threading.html
threading — Thread-based parallelism
If exc_type is SystemExit, the exception is silently ignored. Otherwise, the exception is printed out on sys.stderr. If this function raises an exception, sys.excepthook() is called to handle it.
🌐
Sentry
sentry.io › sentry answers › python › raise an exception in python
Raise an exception in Python | Sentry
June 15, 2023 - Python provides a large number of default exceptions arranged in a class hierarchy from least to most specific. When catching exceptions, all subclasses will be caught by except clauses using their parents. Therefore, the topmost class Exception is likely to be missed in favor of an exception that uses one of its subclasses. Consider the code below: def divide_by_zero(): return 1 / 0 # will fail and raise a ZeroDivisionError try: divide_by_zero() raise Exception("My custom exception.") except Exception as e: print(f"Caught error: {repr(e)}")