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.')
Answer from Aaron Hall on Stack Overflow
🌐
Python documentation
docs.python.org › 3 › tutorial › errors.html
8. Errors and Exceptions — Python 3.14.7 documentation
The use of the else clause is better ... wasn’t raised by the code being protected by the try … except statement. Exception handlers do not handle only exceptions that occur immediately in the try clause, but also those that occur inside functions that are called (even indirectly) in the try clause. For example: >>> def this_fails(): ... x = 1/0 ... >>> try: ... this_fails() ... except ZeroDivisionError as err: ... print('Handling run-time error:', err) ...
🌐
W3Schools
w3schools.com › python › python_try_except.asp
Python Try Except
These exceptions can be handled ... print("An exception occurred") Try it Yourself » · Since the try block raises an error, the except block will be executed....
Discussions

Manually raising (throwing) an exception in Python - Stack Overflow
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.) In Python 3, you can chain Exceptions, which preserve tracebacks: ... These can easily hide and even get into production code. You want to raise ... More on stackoverflow.com
🌐 stackoverflow.com
What's the point of try/except just to raise the exception?
This is called 'boilerplating' in some worlds; it is just a way to be ready for the unexpected, in a structured and sensible way. More on reddit.com
🌐 r/learnpython
56
40
July 25, 2025
python - pythonic way of raising an error within the try block - Stack Overflow
But when you run something on a ... ANY error to the client. ... Save this answer. ... Show activity on this post. You should never use except: because that catches ALL exceptions, including SystemExit, you should probably do: try: if not check(): raise MyNewException() ... More on stackoverflow.com
🌐 stackoverflow.com
How to raise exceptions in try/except and if/else combination?
Yes, this try-except block is redundant here. More on reddit.com
🌐 r/learnpython
7
1
September 11, 2023
People also ask

How do you raise an exception in Python?
Use the raise keyword followed by an exception object, like raise ValueError("invalid metal bar"). Execution stops at that line and the caller has to handle the exception with try/except. Raise the most specific built-in exception that fits, like ValueError or TypeError, instead of a bare Exception.
🌐
boot.dev
boot.dev › blog › python › python exceptions: try, except, and raise
Python Exceptions: Try, Except, and Raise | Boot.dev
What is the difference between raise and return in Python?
return sends a value back to the caller and continues normal execution. raise stops normal execution and forces the caller to handle the error with a try/except block. Use raise when something has gone wrong and the function cannot produce a valid result.
🌐
boot.dev
boot.dev › blog › python › python exceptions: try, except, and raise
Python Exceptions: Try, Except, and Raise | Boot.dev
What is the difference between a syntax error and an exception in Python?
A syntax error means your code is not valid Python and cannot run at all. An exception happens during execution when something goes wrong, like dividing by zero or accessing an invalid index. Syntax errors must be fixed before running. Exceptions can be caught and handled gracefully with try/except.
🌐
boot.dev
boot.dev › blog › python › python exceptions: try, except, and raise
Python Exceptions: Try, Except, and Raise | Boot.dev
🌐
Boot.dev
boot.dev › blog › python › python exceptions: try, except, and raise
Python Exceptions: Try, Except, and Raise | Boot.dev
March 8, 2026 - Exceptions can be caught and handled gracefully so your program doesn't crash. Python uses a try/except pattern for handling exceptions. The try block runs until an exception is raised or it completes, whichever happens first.
Top answer
1 of 11
4330

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.

🌐
Reddit
reddit.com › r/learnpython › what's the point of try/except just to raise the exception?
r/learnpython on Reddit: What's the point of try/except just to raise the exception?
July 25, 2025 -

For context, I'm primarily a database guy but have been using Python a lot lately. I know enough to figure out how to do most things I want to do, but sometimes lack the context of why certain patterns are used/preferred.

Looking through some of the code the software engineers at my organization have written in Python, they make use of try/except blocks frequently and I generally understand why. However, they're often writing except blocks that do nothing but raise the exception. For example:

def main() -> None:  
  try:
    run_etl()
  except Exception as err:
    raise err

Sometimes (not always), I'll at least see logger.error(f"Encountered an exception: {err} before they raise the exception (I have no idea why they're not using logger.exception). Still, since we just let the logging module write to sys.stderr I don't know what we're really gaining.

What is the point of wrapping something in a try/except block when the only thing we're doing is raising the exception? I would understand if we were trying to handle exceptions so the program could continue or if we made use of a finally block to do some sort of post-error cleanup, but we're not. It seems to me like we're just catching the error to raise it, when we could have just let the error get raised directly.

TIA!

Top answer
1 of 20
5
What's the point of try/except just to raise the exception? You are correct. This is pointless, and worse, it obfuscates what the code is doing and makes it harder to maintain. I suspect that what may have happened in some of these places is that it used to do something else in the except block, and that got removed without cleaning up the surrounding code. Another possibility is that some of these are the result of someone blindly copying and pasting code they saw elsewhere. This type of thing happens a lot. Sometimes (not always), I'll at least see logger.error(f"Encountered an exception: {err} before they raise the exception (I have no idea why they're not using logger.exception). Still, since we just let the logging module write to sys.stderr I don't know what we're really gaining. That's pretty common. In production you'd run your code in an environment that captures stderr and stdout, parses them, and then indexes them into a logging system (eg: DataDog or Prometheus). Edit: removed bit about printf debugging, as that isn't what the code in question appears to be doing. (Didn't look closely enough earlier, when I was on my phone.)
2 of 20
5
I will often do this by default until I figure out later how I want to handle specific exception types that can happen as a result of specific situations, because thinking about exception handling can distract me from what I am actually trying to accomplish. It can also help with debugging, because you can put print or log statements in the except section in places you think are relevant and narrow down which one causes the problem. Also, enterprises can have standards that any call that could create an exception should each have its own try except, and you often don't need to do error handling more granularly than the function level, so sometimes you just do this. I think in general it is better practice to have more try excepts than fewer, and I rarely feel it can get excessive
🌐
Real Python
realpython.com › python-exceptions
Python Exceptions: An Introduction – Real Python
March 18, 2026 - The code that follows the except statement is the program’s response to any exceptions in the preceding try clause: As you saw earlier, when syntactically correct code runs into an error, Python will raise an exception error.
Find elsewhere
🌐
Coursera
coursera.org › tutorials › how to catch, raise, and print a python exception
How to Catch, Raise, and Print a Python Exception | Coursera
August 13, 2024 - Additionally, handling exceptions this way enables you to replace the interpreter’s error message with a much more user friendly one. The raise statement allows you to force an error to occur.
🌐
Pylint
pylint.readthedocs.io › en › latest › user_guide › messages › warning › try-except-raise.html
try-except-raise / W0706 - Pylint 4.1.0-dev0 documentation
def execute_calculation(a, b): try: return some_calculation(a, b) except ZeroDivisionError: raise except ArithmeticError: return float('nan') The pylint is able to detect this case and does not produce error.
🌐
Rollbar
rollbar.com › home › throwing exceptions in python
How to Throw Exceptions in Python | Rollbar
With Python, its basic form is “try-except”. The try-except block looks like this: ... try: <--program code--> except: <--exception handling code--> <--program code--> ... Here, the program flow enters the “try” block. If there is an exception, the control jumps to the code in the “except” block. The error handling code you put in the “except” block depends on the type of error you think the code in the “try” block may encounter.
Published: May 22, 2026
🌐
Honeybadger
honeybadger.io › blog › a-guide-to-exception-handling-in-python
The ultimate guide to Python exception handling - Honeybadger Developer Blog
March 28, 2025 - This structured flow helps you handle errors more precisely, keeps the “happy path” logic separate, and ensures that any necessary teardown always happens. Sometimes, you might want to catch multiple types of exceptions, but you want to treat them the same. You can catch multiple exceptions with identical handling logic. Python lets you group them in a single except clause using parentheses. Check out this example: def fetch_data(source): if source == "file": raise FileNotFoundError("File source missing!") elif source == "api": raise ConnectionError("Failed to connect to API!") else: return "Data fetched successfully!" sources = ["file", "api", "database"] for src in sources: try: data = fetch_data(src) print(data) except (FileNotFoundError, ConnectionError) as e: print("Recoverable error:", e) except Exception as ex: print("Unknown error:", ex)
🌐
Python Land
python.land › home › language deep dives › python try except: examples and best practices
Python Try Except: Examples And Best Practices • Python Land Tutorial
January 29, 2026 - When something unexpected occurs, we can raise an exception at the point of the error. When an exception is raised, Python stops the current flow of execution and starts looking for an exception handler that can handle it.
🌐
GeeksforGeeks
geeksforgeeks.org › python › python-try-except
Python Try Except - GeeksforGeeks
June 8, 2026 - When an error occurs inside the try block, Python transfers control to the except block, allowing the program to handle the error safely. Prevents the program from crashing due to runtime errors.
🌐
UTK
web.eecs.utk.edu › ~bvanderz › cs365 › notes › Python › PythonExceptionHandling.html
exception handling
It has a try...except format that ... ExceptionName3: error handling code except: unconditional error handling code raise # re-raises the exception else: code to execute if the try completes successfully....
🌐
Berkeley
pythonnumericalmethods.studentorg.berkeley.edu › notebooks › chapter10.03-Try-Except.html
Try/Except — Python Numerical Methods
--------------------------------------------------------------------------- Exception Traceback (most recent call last) <ipython-input-7-99b32b52c4f8> in <module> 2 3 if x > 5: ----> 4 raise(Exception('x should be less or equal to 5')) Exception: x should be less or equal to 5 · WARNING! Try-except statements should never be used in place of good programming practice. For example, you should not code sloppily and then encase your program in a try-except statement until you have taken every measure you can think of to ensure that your function is working properly. < 10.2 Avoiding Errors | Contents | 10.4 Type Checking >
🌐
Python Morsels
pythonmorsels.com › re-raising-exceptions
Re-raising exceptions in Python - Python Morsels
June 10, 2026 - try: ... except requests.exceptions.RequestException as error: raise BillingError("Error contacting our billing server") We can do that, and Python will still print out the original traceback, as well as the new one, just like it did before:
🌐
YouTube
youtube.com › watch
Python Try-Except and Raise Exception: Practical Example - YouTube
A quick tip on how to use try-except and gracefully handle the errors from external tools like OpenAI API.-----Visit our website for more tutorials: https://...
Published: February 15, 2024
🌐
Reddit
reddit.com › r/learnpython › how to raise exceptions in try/except and if/else combination?
r/learnpython on Reddit: How to raise exceptions in try/except and if/else combination?
September 11, 2023 -

I can never seem to wrap my head around try/except and if/else. I've written a custom exception called InvalidInput. Right now, I have my main code written to raise the exception like this:

data = someString.split('.')[0]
try:
   if data == 'blah':
      #do more stuff
   else:
      raise InvalidInput('You have submitted an invalid value.")
except InvalidInput as e:
    InvalidInput(e)

This is a flask app so it routes the exception to this:

@main.app_errorhandler(InvalidInput)
def handle_invalid_input(error):
  response= jsonify(error.to_dict())
  response.status = error.status_code
  return response

The try/except block seems redundant. Do I need it or could I just raise it from the else and be done with it? I do not surround my whole entire code with a try/except, but I assume raising an exception anywhere means it gets caught by default, whether you explicitly have it contained in a try/except block or not. I assume it's bad form though to not use try/except. I've looked at a lot of stackoverflow threads but I rarely see an example like this. Please help me understand :)

🌐
InventiveHQ
inventivehq.com › home › blog › software engineering › python try except: complete error handling guide
Python Try Except: Complete Error Handling Guide
July 18, 2026 - ... Use a bare raise statement with no arguments inside the except block. It re-raises the exception currently being handled and preserves the original traceback, so the log still points at the real source.
Address: 2305 Historic Decatur Rd, Suite 100, 92106, San Diego