Is your program throwing a fit but those error messages are lost somewhere in the avalanche of print statements? Let's fix that!
Enter stderr - Python's built-in solution for separating your normal program output from your "everything is on fire" messages.
Think of your Python program as having two voices: stdout (its inside voice) and stderr (its "EVERYONE PANIC" voice). stdout is for normal stuff like "Hey, I processed that file" or "Here's your data." stderr is for when things go wrong and your code needs to scream for help.
It's like having a separate lane for emergencies.
Quick example of stderr
Here’s a super simple way to use stderr:
import sys
# Your regular, calm output
print("Everything is fine, just processing some data...")
# Your code's panic mode
print("HELP! SOMETHING'S ON FIRE!", file=sys.stderr)
You could also write it this way with sys.stderr.write()
, which is slightly more efficient but the performance difference is too small to matter for most people:
sys.stderr.write("🔥 ERROR: The thing that shouldn't break just broke 🔥\n")
Real life stderr examples (because theory is boring)
The case of the evil CSV
Ever tried to process a CSV file only to find out it's missing, corrupted, or formatted by someone who thinks commas are optional? Here's how to handle those file mishaps gracefully with stderr:
import sys
import csv
def process_important_file(filename):
try:
with open(filename) as f:
data = csv.DictReader(f)
# Actually do stuff with the data
print("Processing your amazing data...")
except FileNotFoundError:
print(f"Uh oh! '{filename}' is playing hide and seek!", file=sys.stderr)
except csv.Error:
print(f"This CSV is evil and must be stopped!", file=sys.stderr)
# Watch what happens...
process_important_file("definitely_real_file.csv")
Web scraping gone wrong
When web scraping, about a million things can go wrong - the site could be down, your internet could cut out, or the URL might not even exist. Here's how to catch those fails with stderr:
import requests
import sys
def get_website_data(url):
try:
response = requests.get(url)
response.raise_for_status()
print("Got the data! Time to parse...")
except requests.exceptions.RequestException as e:
print(f"The internet has betrayed us: {e}", file=sys.stderr)
# Let's try to scrape a site that doesn't exist
get_website_data("https://totally-real-website.nope")
Pro Tips and Tricks
1. How to save stderr to log files
Sometimes you want to save your error messages to a file for later. Instead of modifying your code, you can use these command-line tricks to redirect stderr wherever you want:
# Only want to save error messages?
python your_script.py 2> errors.log
# This sends just stderr to errors.log
# Want to save regular output and errors separately?
python your_script.py > output.log 2> errors.log
# This sends stdout to output.log and stderr to errors.log
# Want everything in one file?
python your_script.py > everything.log 2>&1
# This sends everything to everything.log
# (the 2>&1 means "send stderr to the same place as stdout")
In the terminal, these special numbers are shortcuts for different output streams:
2
means stderr (error messages)1
means stdout (regular output)>
means "send to a file"
2. Format your errors (because style matters)
Make your error messages more useful by adding timestamps - super helpful when debugging what went wrong and when:
import sys
from datetime import datetime
def fancy_error(message):
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print(f"[{timestamp}] 🚨 {message} 🚨", file=sys.stderr)
fancy_error("The database is having an existential crisis!")
3. The ultimate pro tip: use Rollbar
Look, stderr is great for development and simple scripts. But when your code is out there in the wild, you need something more robust. Enter Rollbar.
Level up your error handling with Rollbar
Rollbar is like stderr on steroids. Instead of just screaming into the void, Rollbar:
- Catches and groups similar errors
- Shows you exactly where things went wrong
- Tells you which deploy broke things
- Notifies you when new issues pop up
- Tracks error trends over time
Here's how easy it is to set up:
Installation
pip install rollbar
Basic usage
import rollbar
rollbar.init('your_access_token')
def risky_business():
try:
# Do something dangerous
raise Exception("Something went terribly wrong!")
except Exception as e:
rollbar.report_exc_info()
# You can still use stderr locally too!
print(f"Error reported to Rollbar: {e}", file=sys.stderr)
Want to learn more? Check out Rollbar’s Python SDK docs and create a Rollbar account for your project today. Rollbar has a generous free trier of 5,000 error events monthly.
Remember: Good error handling is like a smoke detector. You hope you never need it, but you'll be really glad it's there when something catches fire. 🔥