How do I print an exception in Python?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Printing an exception in Python can mean different things depending on what you need. Sometimes you only want the error message, and sometimes you need the full traceback so you can see where the failure came from. The right choice depends on whether you are debugging a small script, building a service, or recording production failures.
Core Sections
Print the exception object for the message only
The simplest form is to catch the exception and print the exception object. That gives you the exception message, but not the full traceback.
This is useful when the message itself is enough, such as in a short script or a command-line tool that wants to show a concise error to the user.
The limitation is that it does not tell you where the exception originated unless your code already makes that obvious.
Use traceback.print_exc() for debugging
If you need the stack trace, use the traceback module.
This prints the full traceback to standard error, which is usually what you want during debugging. It shows the line where the exception happened and the call path that led there.
That makes it much more useful than print(exc) when the failure is inside a deeper call stack.
Use logging.exception() in application code
For real applications, printing directly to standard output is often not enough. Python’s logging module is usually the better choice because it captures structured messages and can write to files, consoles, or centralized log systems.
logging.exception() is especially convenient because it automatically includes traceback information when called inside an except block.
This is generally the strongest default for web apps, background workers, and long-running services.
Know the difference between user-facing and developer-facing output
A common design mistake is showing raw exception details directly to end users. The traceback is valuable to developers, but it can be noisy, confusing, or even sensitive in user-facing contexts.
A better pattern is:
- log the full exception internally
- show a short safe message to the user
This keeps debugging information available without leaking implementation details to the outside.
Re-raising after printing or logging
Sometimes you want to record the exception and still let it propagate. In that case, log it and then re-raise.
This pattern is useful when the current layer wants to add context but should not silently swallow the error.
Avoid broad exception handling unless you mean it
It is tempting to write except Exception as exc: everywhere and just print the error. That is acceptable for a top-level entry point, but lower-level code should usually catch specific exceptions.
Catching everything too early can hide programming errors, make recovery logic too broad, and produce logs that are harder to interpret.
Common Pitfalls
- Using
print(exc)when you really need the full traceback leaves out the most useful debugging information. - Catching
Exceptiontoo broadly can hide bugs that should fail fast instead of being silently logged. - Printing raw tracebacks directly to end users exposes details that belong in internal logs, not in user interfaces.
- Logging only a custom message without the exception context makes later debugging much harder.
- Swallowing the exception after printing it can let the program continue in an invalid state.
Summary
- '
print(exc)shows only the exception message.' - '
traceback.print_exc()shows the full traceback and is better for interactive debugging.' - '
logging.exception()is usually the best choice in real applications because it records both message and traceback.' - Separate user-facing error messages from developer-facing diagnostic details.
- If the exception should still fail the operation, log it and then re-raise it.

