Python
Exception Handling
Error Messages
Debugging
Programming Tips

How to get exception message in Python properly

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In Python, the most common way to get an exception message is to catch the exception as a variable and call str() on it. That is enough for many cases, but it is not the whole story. Good error handling also needs to consider exception type, traceback, and whether the message should be shown to a user, logged for operators, or re-raised for another layer to handle.

Catch the Exception Object

The normal pattern is:

python
1try:
2    int("abc")
3except ValueError as exc:
4    print(str(exc))

For built-in exceptions, str(exc) usually gives the human-readable message. This is the most direct answer when you just want the message text.

str, repr, and args Are Not the Same

An exception object exposes several useful views:

  • 'str(exc) gives the normal readable message'
  • 'repr(exc) shows a more debugging-oriented representation'
  • 'exc.args contains the raw argument tuple passed to the exception'
python
1try:
2    {}["missing"]
3except KeyError as exc:
4    print("str:", str(exc))
5    print("repr:", repr(exc))
6    print("args:", exc.args)

These can look different. For debugging, repr(exc) is often more informative. For user-facing error text, str(exc) is usually the better choice.

Use Logging for Real Error Reporting

If an exception should be recorded, logging the traceback is often more useful than printing only the message.

python
1import logging
2
3logging.basicConfig(level=logging.ERROR)
4
5try:
6    1 / 0
7except ZeroDivisionError:
8    logging.exception("calculation failed")

logging.exception(...) automatically includes the traceback when called inside an except block. That is usually better than manually logging only str(exc), because the stack context matters.

Get the Full Traceback When Needed

Sometimes you need the full traceback as text, for example in custom error reporting or test diagnostics. Use the traceback module.

python
1import traceback
2
3try:
4    int("abc")
5except ValueError as exc:
6    message = str(exc)
7    trace = traceback.format_exc()
8    print(message)
9    print(trace)

This gives you both the short human message and the full failure context.

Be Careful with Broad Exception Handling

Getting the message properly also means catching the right exception. Code such as this is usually too broad:

python
1try:
2    risky_operation()
3except Exception as exc:
4    print(str(exc))

It may be acceptable at an application boundary, but deep inside business logic it can hide useful distinctions. Often the better pattern is:

  • catch a specific exception when you know how to handle it
  • log or re-raise unexpected exceptions

That keeps error handling explicit instead of flattening everything into one generic message.

Chained Exceptions Need Attention

Python supports exception chaining with raise ... from .... In those cases, the top-level message may not tell the whole story.

python
1try:
2    int("abc")
3except ValueError as exc:
4    raise RuntimeError("could not parse user input") from exc

If this is caught later, the visible message may be the RuntimeError text, but the original ValueError is still attached as __cause__. That matters when debugging layered code.

Do Not Depend on Message Text for Program Logic

Exception messages are for humans. They can vary by Python version, library version, and exception type. If your code needs to branch on the error, branch on the exception class, not the string message.

Bad pattern:

python
except Exception as exc:
    if "not found" in str(exc):
        ...

Better pattern:

python
except FileNotFoundError:
    ...

This makes the code more stable and easier to understand.

Common Pitfalls

  • Treating str(exc) as the only useful exception detail when traceback or type also matters.
  • Catching overly broad exceptions and flattening unrelated failures into one message.
  • Logging only the message and losing the traceback.
  • Parsing exception message text to drive program logic.
  • Forgetting that chained exceptions may hide the original lower-level cause unless inspected.

Summary

  • The usual way to get an exception message in Python is str(exc) inside except ... as exc.
  • 'repr(exc) and exc.args can also be useful, especially during debugging.'
  • For operational visibility, prefer logging.exception(...) or traceback.format_exc() over bare prints.
  • Catch specific exception types whenever possible.
  • Use exception classes for logic and messages for humans.

Course illustration
Course illustration

All Rights Reserved.