Skip to content

Commit 7a52f24

Browse files
committed
refactor: handle metrics extraction failures gracefully
Move the metrics_extractor call inside _track_from_metrics_extractor so extraction errors are caught and logged without bubbling up. When extraction fails or returns None, only the wall-clock duration is tracked — success/error is left untouched since the underlying model call itself succeeded. Also tighten the tool_calls check to access metrics.tool_calls directly, mirroring how metrics.usage is accessed.
1 parent 89d0ad7 commit 7a52f24

1 file changed

Lines changed: 19 additions & 6 deletions

File tree

packages/sdk/server-ai/src/ldai/tracker.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,22 @@ def track_duration_of(self, func):
279279

280280
return result
281281

282-
def _track_from_metrics_extractor(self, metrics: Any, elapsed_ms: int) -> None:
282+
def _track_from_metrics_extractor(
283+
self,
284+
result: Any,
285+
metrics_extractor: Callable[[Any], Any],
286+
elapsed_ms: int,
287+
) -> None:
288+
metrics = None
289+
try:
290+
metrics = metrics_extractor(result)
291+
except Exception as exc:
292+
log.warning("Failed to extract metrics: %s", exc)
293+
294+
if metrics is None:
295+
self.track_duration(elapsed_ms)
296+
return
297+
283298
reported_ms = getattr(metrics, 'duration_ms', None)
284299
self.track_duration(reported_ms if reported_ms is not None else elapsed_ms)
285300
if metrics.success:
@@ -288,7 +303,7 @@ def _track_from_metrics_extractor(self, metrics: Any, elapsed_ms: int) -> None:
288303
self.track_error()
289304
if metrics.usage:
290305
self.track_tokens(metrics.usage)
291-
if getattr(metrics, 'tool_calls', None) is not None:
306+
if metrics.tool_calls is not None:
292307
self.track_tool_calls(metrics.tool_calls)
293308

294309
def track_metrics_of(
@@ -326,8 +341,7 @@ def track_metrics_of(
326341
raise err
327342

328343
elapsed_ms = (time.perf_counter_ns() - start_ns) // 1_000_000
329-
metrics = metrics_extractor(result)
330-
self._track_from_metrics_extractor(metrics, elapsed_ms)
344+
self._track_from_metrics_extractor(result, metrics_extractor, elapsed_ms)
331345
return result
332346

333347
async def track_metrics_of_async(self, metrics_extractor, func):
@@ -355,8 +369,7 @@ async def track_metrics_of_async(self, metrics_extractor, func):
355369
raise err
356370

357371
elapsed_ms = (time.perf_counter_ns() - start_ns) // 1_000_000
358-
metrics = metrics_extractor(result)
359-
self._track_from_metrics_extractor(metrics, elapsed_ms)
372+
self._track_from_metrics_extractor(result, metrics_extractor, elapsed_ms)
360373
return result
361374

362375
def track_judge_result(self, judge_result: Any) -> None:

0 commit comments

Comments
 (0)