42 lines
1.4 KiB
Python
42 lines
1.4 KiB
Python
"""Regression: langfuse_client surface + span context manager behaviour.
|
|
|
|
Bugs captured:
|
|
1. AttributeError: module 'api.langfuse_client' has no attribute 'span'
|
|
— the module was at the old observability.py shape with `langfuse_span`.
|
|
2. RuntimeError: generator didn't stop after throw()
|
|
— the @contextmanager wrapped the user's `with` body in `try/except`
|
|
and yielded a second value on exception, which @contextmanager rejects.
|
|
"""
|
|
|
|
import pytest
|
|
|
|
from api import langfuse_client as lf
|
|
|
|
|
|
def test_public_surface():
|
|
assert callable(lf.span)
|
|
assert callable(lf.flush)
|
|
assert callable(lf.get_client)
|
|
|
|
|
|
def test_span_returns_nullspan_without_keys(monkeypatch):
|
|
# Ensure no keys → no client → null span.
|
|
from api.config import get_settings
|
|
get_settings.cache_clear()
|
|
monkeypatch.setenv("LANGFUSE_PUBLIC_KEY", "")
|
|
monkeypatch.setenv("LANGFUSE_SECRET_KEY", "")
|
|
# Reset cached client too
|
|
lf._client = None
|
|
with lf.span("t") as s:
|
|
assert isinstance(s, lf._NullSpan)
|
|
s.update(output={"x": 1}) # no-op should not raise
|
|
get_settings.cache_clear()
|
|
|
|
|
|
def test_span_body_exception_propagates():
|
|
"""The body's exception MUST propagate — wrapping it inside @contextmanager
|
|
causes 'generator didn't stop after throw()' if the except clause yields."""
|
|
with pytest.raises(ValueError, match="kaboom"):
|
|
with lf.span("t"):
|
|
raise ValueError("kaboom")
|