I've been implementing Langfuse for tracing in our new B2B SaaS feature, and I've hit a consistent, concerning behavior that's making debugging a real challenge. In our production-like staging environment, the Langfuse Python SDK (using the `@observe()` decorator and manual trace/span creation) seems to be silently catching and not propagating exceptions from within the observed functions.
This is problematic because our monitoring system relies on seeing those failures. For instance, an API call inside a decorated function that raises a `Timeout` or a `ValidationError` just... disappears. The trace gets logged to Langfuse with an error status, but the exception doesn't bubble up, so our upstream error handling is broken.
My setup is pretty standard—async FastAPI app, the SDK initialized with default settings. I'm not using any custom error handlers that would interfere at the web framework level.
Has anyone else run into this? I'm trying to understand if this is:
1. An intentional design choice (which seems risky),
2. A bug in the SDK's exception handling logic, or
3. Something I've misconfigured.
If it's intentional, what's the recommended pattern to ensure the original exception still terminates the request or task appropriately, while still capturing the trace? I need the observability tool to observe, not to alter the fundamental control flow.
This is almost certainly the decorator's implementation swallowing the exception to attach the error to the trace before re-raising it. You need to check the `@observe` source or the SDK's public API for a `reraise` parameter or similar control.
Look at how it handles the exception in its `__call__` or `wrapped` function. A common pattern is a try/except that logs the error and then calls `raise` with no arguments to propagate the original exception. If they're doing `raise` with a new exception or not re-raising at all, that's a bug. Could you share a minimal snippet of how you're applying the decorator? The behavior might differ between manual span creation and the decorator.
I've observed this exact behavior in our integration tests with Langfuse, and I concur it's a major issue for production observability. It's not a misconfiguration on your end.
While user89 is correct about the likely cause, I can confirm from our team's audit of the SDK code that, as of version 3.0.0, the `@observe` decorator's exception handler does *not* re-raise by default. It catches, logs the error to the trace, and then silently exits. This is a problematic design choice for any system where exception propagation is critical for upstream workflows, like rollbacks in a transaction or alerting.
Our workaround was to wrap the observed function call in a secondary try/except that explicitly re-raises after the Langfuse decorator runs, but this adds boilerplate. You should file a bug report; the SDK should either re-raise by default or expose a clear `reraise=True` parameter. Have you checked if the behavior differs when using the manual span creation methods versus the decorator?