Skip to content

Commit 995fe65

Browse files
committed
Log request and upstream model names in errors
1 parent 6c77247 commit 995fe65

3 files changed

Lines changed: 112 additions & 15 deletions

File tree

main.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,10 +1590,13 @@ async def execute_attempt(attempt):
15901590

15911591
def after_failure(attempt, exc, status_code, error_message):
15921592
_ = exc
1593+
request_model, actual_model = _log_model_names(request_data.model, attempt.original_model)
15931594
logger.error(
1594-
"Error %s with provider %s API key: %s: %s",
1595+
"Error %s with provider %s request_model=%s actual_model=%s API key: %s: %s",
15951596
status_code,
15961597
attempt.provider_name,
1598+
request_model,
1599+
actual_model,
15971600
attempt.provider_api_key_raw,
15981601
error_message,
15991602
)
@@ -1654,6 +1657,11 @@ def _normalize_responses_compact_upstream_url(base_url: str, engine: str) -> str
16541657

16551658
return f"{base}/compact"
16561659

1660+
def _log_model_names(request_model_name: Any, actual_model_name: Any = None) -> tuple[str, str]:
1661+
request_model = str(request_model_name or "-")
1662+
actual_model = str(actual_model_name or request_model)
1663+
return request_model, actual_model
1664+
16571665
def _responses_request_id(current_info: Any) -> str:
16581666
if isinstance(current_info, dict):
16591667
request_id = current_info.get("request_id")
@@ -2100,13 +2108,15 @@ async def proxy_stream():
21002108
except RESPONSES_STREAM_NETWORK_ERRORS as e:
21012109
stream_stage = "post-commit" if stream_committed else "preflight"
21022110
error_text = str(e) or type(e).__name__
2111+
request_model, actual_model = _log_model_names(request_model_name, original_model)
21032112
trace_logger.warning(
2104-
"%s upstream stream aborted stage=%s error_type=%s request_id=%s model=%s provider=%s key=%s upstream_url=%s: %s",
2113+
"%s upstream stream aborted stage=%s error_type=%s request_id=%s request_model=%s actual_model=%s provider=%s key=%s upstream_url=%s: %s",
21052114
endpoint,
21062115
stream_stage,
21072116
type(e).__name__,
21082117
request_id,
2109-
request_model_name,
2118+
request_model,
2119+
actual_model,
21102120
provider_name,
21112121
attempt.provider_api_key_raw,
21122122
upstream_url,
@@ -2173,12 +2183,14 @@ def after_failure(attempt, exc, status_code, error_message):
21732183

21742184
upstream_url = attempt.state.get("upstream_url", "")
21752185
failure_stage = attempt.state.get("failure_stage")
2186+
request_model, actual_model = _log_model_names(request_model_name, attempt.original_model)
21762187
if failure_stage == "auth" and isinstance(exc, ValueError):
21772188
trace_logger.error(
2178-
"%s invalid codex api key request_id=%s model=%s provider=%s key=%s upstream_url=%s: %s",
2189+
"%s invalid codex api key request_id=%s request_model=%s actual_model=%s provider=%s key=%s upstream_url=%s: %s",
21792190
endpoint,
21802191
request_id,
2181-
request_model_name,
2192+
request_model,
2193+
actual_model,
21822194
attempt.provider_name,
21832195
attempt.provider_api_key_raw,
21842196
upstream_url,
@@ -2187,10 +2199,11 @@ def after_failure(attempt, exc, status_code, error_message):
21872199
return
21882200
if failure_stage == "auth" and isinstance(exc, HTTPException):
21892201
trace_logger.error(
2190-
"%s codex token refresh failed request_id=%s model=%s provider=%s key=%s upstream_url=%s: %s",
2202+
"%s codex token refresh failed request_id=%s request_model=%s actual_model=%s provider=%s key=%s upstream_url=%s: %s",
21912203
endpoint,
21922204
request_id,
2193-
request_model_name,
2205+
request_model,
2206+
actual_model,
21942207
attempt.provider_name,
21952208
attempt.provider_api_key_raw,
21962209
upstream_url,
@@ -2199,12 +2212,13 @@ def after_failure(attempt, exc, status_code, error_message):
21992212
return
22002213

22012214
trace_logger.error(
2202-
"%s upstream error status=%s error_type=%s request_id=%s model=%s provider=%s key=%s upstream_url=%s: %s",
2215+
"%s upstream error status=%s error_type=%s request_id=%s request_model=%s actual_model=%s provider=%s key=%s upstream_url=%s: %s",
22032216
endpoint,
22042217
status_code,
22052218
type(exc).__name__,
22062219
request_id,
2207-
request_model_name,
2220+
request_model,
2221+
actual_model,
22082222
attempt.state.get("channel_id", attempt.provider_name),
22092223
attempt.provider_api_key_raw,
22102224
upstream_url,

test/test_refactor_routing.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import main
88
from fastapi import BackgroundTasks
9+
from fastapi import HTTPException
910
from starlette.responses import Response
1011
from core.models import RequestModel
1112
from routing import build_api_key_models_map
@@ -147,3 +148,81 @@ async def run_test():
147148
assert response.status_code == 200
148149

149150
asyncio.run(run_test())
151+
152+
153+
def test_model_request_handler_error_log_includes_request_and_actual_model(monkeypatch):
154+
provider_name = "provider-a"
155+
156+
class DummyCircularList:
157+
async def is_all_rate_limited(self, model):
158+
return False
159+
160+
async def next(self, model):
161+
return "provider-key-1"
162+
163+
def get_items_count(self):
164+
return 1
165+
166+
async def fake_get_right_order_providers(request_model_name, config, api_index, scheduling_algorithm):
167+
return [
168+
{
169+
"provider": provider_name,
170+
"_model_dict_cache": {"friendly-model": "gpt-4.1"},
171+
"base_url": "https://example.com/v1/chat/completions",
172+
"api": ["provider-key-1"],
173+
"preferences": {},
174+
}
175+
]
176+
177+
async def fake_process_request(
178+
request,
179+
provider,
180+
background_tasks,
181+
endpoint=None,
182+
role=None,
183+
timeout_value=0,
184+
keepalive_interval=None,
185+
provider_api_key_raw=None,
186+
):
187+
raise HTTPException(status_code=502, detail="bad gateway")
188+
189+
error_logs = []
190+
191+
def fake_error(msg, *args, **kwargs):
192+
_ = kwargs
193+
error_logs.append(msg % args if args else msg)
194+
195+
monkeypatch.setitem(main.provider_api_circular_list, provider_name, DummyCircularList())
196+
monkeypatch.setattr(main, "get_right_order_providers", fake_get_right_order_providers)
197+
monkeypatch.setattr(main, "process_request", fake_process_request)
198+
monkeypatch.setattr(main.logger, "error", fake_error)
199+
200+
main.app.state.config = {
201+
"api_keys": [
202+
{
203+
"api": "sk-test",
204+
"model": ["friendly-model"],
205+
"preferences": {"AUTO_RETRY": False},
206+
}
207+
]
208+
}
209+
main.app.state.provider_timeouts = {"global": {"default": 30}}
210+
main.app.state.keepalive_interval = {"global": {"default": 99999}}
211+
212+
async def run_test():
213+
handler = main.ModelRequestHandler()
214+
response = await handler.request_model(
215+
RequestModel(
216+
model="friendly-model",
217+
messages=[{"role": "user", "content": "hello"}],
218+
stream=False,
219+
),
220+
0,
221+
BackgroundTasks(),
222+
)
223+
assert response.status_code == 502
224+
225+
asyncio.run(run_test())
226+
227+
assert any("request_model=friendly-model" in log for log in error_logs)
228+
assert any("actual_model=gpt-4.1" in log for log in error_logs)

test/test_responses_retry.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ async def fake_get_right_order_providers(request_model_name, config, api_index,
445445
return [
446446
{
447447
"provider": provider_name,
448-
"_model_dict_cache": {"gpt-5.4": "gpt-5.4"},
448+
"_model_dict_cache": {"friendly-model": "gpt-5.4"},
449449
"base_url": "https://provider-a.example/v1/responses",
450450
"api": ["key-a"],
451451
"preferences": {},
@@ -467,7 +467,7 @@ def fake_error(msg, *args, **kwargs):
467467
"api_keys": [
468468
{
469469
"api": "sk-test",
470-
"model": ["gpt-5.4"],
470+
"model": ["friendly-model"],
471471
"preferences": {"AUTO_RETRY": False},
472472
}
473473
]
@@ -490,7 +490,7 @@ def fake_error(msg, *args, **kwargs):
490490

491491
response = _run_responses_request(
492492
ResponsesRequest(
493-
model="gpt-5.4",
493+
model="friendly-model",
494494
input=[{"role": "user", "content": "hello"}],
495495
),
496496
endpoint="/v1/responses/compact",
@@ -499,6 +499,8 @@ def fake_error(msg, *args, **kwargs):
499499
assert response.status_code == 404
500500
assert any("/v1/responses/compact upstream error status=404" in log for log in error_logs)
501501
assert any("request_id=req-test" in log for log in error_logs)
502+
assert any("request_model=friendly-model" in log for log in error_logs)
503+
assert any("actual_model=gpt-5.4" in log for log in error_logs)
502504
assert any("upstream_url=https://provider-a.example/v1/responses/compact" in log for log in error_logs)
503505

504506

@@ -950,7 +952,7 @@ async def fake_get_right_order_providers(request_model_name, config, api_index,
950952
return [
951953
{
952954
"provider": provider_name,
953-
"_model_dict_cache": {"gpt-5.4": "gpt-5.4"},
955+
"_model_dict_cache": {"friendly-model": "gpt-5.4"},
954956
"base_url": "https://provider-a.example/v1/responses",
955957
"api": ["key-a"],
956958
"preferences": {},
@@ -972,7 +974,7 @@ def fake_warning(msg, *args, **kwargs):
972974
"api_keys": [
973975
{
974976
"api": "sk-test",
975-
"model": ["gpt-5.4"],
977+
"model": ["friendly-model"],
976978
"preferences": {"AUTO_RETRY": False},
977979
}
978980
]
@@ -996,7 +998,7 @@ def fake_warning(msg, *args, **kwargs):
996998

997999
response, body = _run_responses_request_with_stream_body(
9981000
ResponsesRequest(
999-
model="gpt-5.4",
1001+
model="friendly-model",
10001002
input=[{"role": "user", "content": "hello"}],
10011003
stream=True,
10021004
),
@@ -1008,6 +1010,8 @@ def fake_warning(msg, *args, **kwargs):
10081010
assert body.endswith("data: [DONE]\n\n")
10091011
assert any("/v1/responses/compact upstream stream aborted stage=post-commit" in log for log in warning_logs)
10101012
assert any("error_type=RemoteProtocolError" in log for log in warning_logs)
1013+
assert any("request_model=friendly-model" in log for log in warning_logs)
1014+
assert any("actual_model=gpt-5.4" in log for log in warning_logs)
10111015
assert any("request_id=req-test" in log for log in warning_logs)
10121016
assert any("upstream_url=https://provider-a.example/v1/responses/compact" in log for log in warning_logs)
10131017

0 commit comments

Comments
 (0)