fix(daily-activity): keep daily activity up when the guardrail breakdown query fails, and treat an empty model filter as none

A database error from the guardrail spend query now logs a warning and returns the response without guardrails, where it used to fail the whole aggregated response with a 500. An empty model= no longer drops the guardrail breakdown, matching how the rest of the endpoint already ignores it. The daily activity golden files and fixtures gain the empty guardrails key every breakdown now carries
This commit is contained in:
Mrinal Chanshetty 2026-10-28 10:59:29 -07:00
parent 7e4f25a5e2
commit 002cab191a
8 changed files with 21 additions and 8 deletions

View file

@ -1049,6 +1049,18 @@ def _with_guardrail_breakdown(
return tuple(_day_with_guardrails(day, rows_by_date.get(day.date.strftime("%Y-%m-%d"), ())) for day in results)
async def _guardrail_spend_or_empty(
repository: DailyActivityRepository, scope: DailyActivityScope
) -> tuple[GuardrailSpendRow, ...]:
from prisma.errors import PrismaError
try:
return await repository.guardrail_spend(scope)
except PrismaError as exc:
verbose_proxy_logger.warning("Returning daily activity without its guardrail breakdown: %s", exc)
return ()
async def get_daily_activity_aggregated(
repository: DailyActivityRepository,
scope: DailyActivityScope,
@ -1063,8 +1075,8 @@ async def get_daily_activity_aggregated(
repository.aggregated(
scope, include_entity_breakdown=include_entity_breakdown, api_key_limit=api_key_limit
),
repository.guardrail_spend(scope)
if include_guardrail_breakdown and scope.model is None
_guardrail_spend_or_empty(repository, scope)
if include_guardrail_breakdown and not scope.model
else asyncio.sleep(0, result=()),
)
records: Final = aggregated_rows.grouping_rows

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -26,7 +26,7 @@
},
"results": [
{
"breakdown": {
"breakdown": {"guardrails": {},
"api_keys": {
"key-a": {
"metadata": {

View file

@ -26,7 +26,7 @@
},
"results": [
{
"breakdown": {
"breakdown": {"guardrails": {},
"api_keys": {
"key-a": {
"metadata": {

View file

@ -26,7 +26,7 @@
},
"results": [
{
"breakdown": {
"breakdown": {"guardrails": {},
"api_keys": {
"key-a": {
"metadata": {

View file

@ -26,7 +26,7 @@
},
"results": [
{
"breakdown": {
"breakdown": {"guardrails": {},
"api_keys": {
"key-a": {
"metadata": {

View file

@ -326,6 +326,7 @@ async def test_get_daily_activity_aggregated_breaks_down_guardrail_spend(gateway
"topic-filter": (pytest.approx(0.01), {"key-b": 0.0}),
}
assert _guardrail_spend(_day_breakdown(gateway, day, model="gpt-5")) == {}
assert _guardrail_spend(_day_breakdown(gateway, day, model="")) == _guardrail_spend(everyone)
finally:
_clean(day)
write_rows('DELETE FROM "LiteLLM_DailyGuardrailUsageUnits" WHERE date = %s', (day,))