Flask's request-scoped error handling makes it hard to see what breaks in production. An unhandled exception kills a request and you never hear about it unless a user tells you — or worse, never hear about it at all. Flask error tracking with the Sentry SDK changes that — every exception lands in a dashboard with its full context, so you catch and fix production bugs before your users do.
The payoff is huge. You go from discovering a production bug in a one-star review to seeing it grouped in your error dashboard the moment it lands. Stack traces show exactly which line failed. Breadcrumbs show the sequence of events leading up to the crash. Request context shows which user was affected and what they were trying to do. This guide walks through adding production-grade error tracking to a Flask app in under ten minutes using the Sentry SDK pointed at LightTrace.
Install and initialize the SDK
Start by adding the Sentry SDK for Python:
pip install sentry-sdk[flask]
Then initialize it before your Flask app runs, passing a LightTrace DSN:
import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration
from flask import Flask
sentry_sdk.init(
dsn="https://<key>@your-lighttrace-host/1",
integrations=[FlaskIntegration()],
environment="production",
release="api@1.2.0",
traces_sample_rate=1.0,
)
app = Flask(__name__)
That single init call hooks Sentry into Flask's error handlers. Now any unhandled exception in a request will be captured and sent to LightTrace automatically. Because LightTrace is Sentry-SDK-compatible, you use the standard Python SDK and change only the dsn.
The FlaskIntegration() is what connects the SDK to Flask's request lifecycle. It captures request data — method, URL, headers, query parameters — and associates it with each error so you can see exactly what was happening when it broke.
Capture exceptions in route handlers
Flask won't automatically catch exceptions that your code handles and doesn't re-raise. For deliberate error handling, explicitly tell Sentry:
from flask import jsonify
from sentry_sdk import capture_exception
@app.route("/api/users/<user_id>", methods=["GET"])
def get_user(user_id):
try:
user = database.query_user(user_id)
if not user:
return jsonify({"error": "not found"}), 404
return jsonify(user)
except DatabaseError as e:
capture_exception(e)
return jsonify({"error": "database error"}), 500
Use capture_exception() when you catch an exception but want error tracking to see it. This is useful for background jobs, error handlers, or any place where you're being defensive but want to monitor what's failing.
Add context that makes debugging fast
Raw stack traces are a starting point. Context — who made the request, what they were doing, which release has the bug — is what cuts mean-time-to-resolution. Set user info and add breadcrumbs at key points:
from sentry_sdk import set_user, add_breadcrumb
@app.before_request
def before_request():
if current_user:
set_user({
"id": current_user.id,
"email": current_user.email,
})
@app.route("/api/orders", methods=["POST"])
def create_order():
add_breadcrumb(
category="order",
message="Order validation started",
level="info",
)
add_breadcrumb(
category="payment",
message=f"Charging ${order.total}",
level="info",
)
result = payment_service.charge(order.total)
return jsonify({"order_id": order.id})
Now every error report carries the breadcrumb trail that led to it — the requests, validations, and state changes that came before the crash. That trail turns a cryptic stack trace into a clear narrative you can reproduce.
Add breadcrumbs at the start of complex operations (payments, database writes) so if they fail you have the full picture. Skip noise like every single request log; focus on the business-logic moments.
Monitor async tasks and background jobs
Flask background tasks (Celery, RQ, etc.) don't live in the request-response cycle, so Sentry won't see their errors by default. Wire them up explicitly:
from celery import Celery
app.config['CELERY_BROKER_URL'] = 'redis://localhost:6379'
celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL'])
celery.conf.update(app.config)
from sentry_sdk.integrations.celery import CeleryIntegration
sentry_sdk.init(
dsn="https://<key>@your-lighttrace-host/1",
integrations=[
FlaskIntegration(),
CeleryIntegration(),
],
environment="production",
)
@celery.task
def send_email(user_id):
user = db.get_user(user_id)
# If this fails, Sentry sees it
email_service.send(user.email, "Welcome!")
The CeleryIntegration ensures that task failures land in your error tracker with the same grouping and context as request errors. Silent background job failures are among the most expensive bugs to debug — this makes them visible.
Test that it's working
Before deploying to production, verify the SDK is reporting to LightTrace. This is critical — you don't want to discover that error reporting is broken when you're in the middle of a production incident.
# In a test route or management command
from sentry_sdk import capture_message
@app.route("/test-sentry", methods=["GET"])
def test_sentry():
capture_message("Test message from Flask", level="info")
raise ValueError("Test error from Flask")
Visit that route, then check your LightTrace dashboard within a few seconds. You should see the test message and the test error grouped as a single issue, with the full request context attached. The grouping uses a fingerprint — so identical errors from different requests all collapse into one issue you can fix once and be done.
Once you confirm it's working, remove the test route and the test code before shipping to production. Don't accidentally leave debug endpoints in production where they might be exploited or expose information about your stack.
Common Flask errors to watch
A few patterns show up constantly in Flask apps. With error tracking in place, each becomes an actionable issue instead of a silent failure:
- Database connection errors during request handling — track them so you know when your database is timing out, the pool is exhausted, or the connection drops mid-transaction. Without tracking, a request times out silently and the user gets a 500, but you never see the root cause.
- Third-party API failures (payment gateways, analytics, CDN, email services) — breadcrumbs reveal which requests triggered the failure and in what sequence, making it trivial to replay the scenario and fix it.
- Unhandled exceptions in middleware or request hooks —
before_request,after_request,teardown_requesterrors are easy to miss because they live outside your route handlers; Sentry catches them all and associates them with the request that triggered them. - Background job failures — tasks that fail silently (Celery, RQ, APScheduler) are invisible without explicit error tracking. A job that processes refunds or sends password-reset emails failing silently is a business-critical bug you need to know about immediately.
Connect these to how to debug production errors for the deeper playbook on triage and response.
Next steps: distributed tracing and performance
Once error tracking is live, you have half the picture. Add distributed tracing to see where requests actually slow down. Tag errors by release to spot which deploy introduced a regression, and set up alert rules so you wake up for new issues, not every event.
For a faster-moving Flask shop running multiple services, cross-project tracing lets you trace a user's request across the web frontend, your API, and downstream services in one waterfall. That's transformational when debugging high-latency or cascading failures. See cross-project tracing for the full setup.
If you're comparing options, check out the best Sentry alternatives guide for what to look for in an error tracker — SDK coverage, grouping quality, and pricing all matter when scaling.
Start tracking errors in minutes
Initialize the Sentry SDK on your Flask app and point it at LightTrace — capture your first grouped errors and start fixing production bugs faster.
That's the full setup. Your Flask app now reports every unhandled exception with full context, breadcrumbs, and user info. Stack traces are grouped so one bug is one line in your dashboard. Errors that were silent are now visible. Deploy with confidence knowing you'll see the next production issue before your users do.