Problem
request_json in src/model_router/_http.py only converts HTTPError and URLError into RouterError. Two other common failures leak out as different exception types:
| Situation |
What route() raises today |
| Server answers 200 with a non-JSON body (proxy / CDN error page) |
json.JSONDecodeError |
| Connection opens, then the response read times out |
TimeoutError |
The README tells users to write except RouterError: and fall back to a default model (see "Using it in an agent"). With these leaks, that fallback never runs and the agent crashes instead.
Reproduce
import io
from unittest.mock import MagicMock, patch
from model_router._http import request_json
resp = MagicMock()
resp.__enter__.return_value = io.BytesIO(b"<html>oops</html>")
with patch("urllib.request.urlopen", return_value=resp):
request_json("https://x.test") # json.JSONDecodeError, expected RouterError
Suggested fix
In request_json, also catch json.JSONDecodeError and TimeoutError (plus OSError for connection resets) and re-raise as RouterError(...) from e. Keep the original exception chained.
Done when
Problem
request_jsoninsrc/model_router/_http.pyonly convertsHTTPErrorandURLErrorintoRouterError. Two other common failures leak out as different exception types:route()raises todayjson.JSONDecodeErrorTimeoutErrorThe README tells users to write
except RouterError:and fall back to a default model (see "Using it in an agent"). With these leaks, that fallback never runs and the agent crashes instead.Reproduce
Suggested fix
In
request_json, also catchjson.JSONDecodeErrorandTimeoutError(plusOSErrorfor connection resets) and re-raise asRouterError(...) from e. Keep the original exception chained.Done when
RouterErrortests/test_http.py