mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-28 01:32:17 +00:00
fix(vertex): distinguish missing/unreadable credential file from invalid JSON
This commit is contained in:
parent
1af7a403c6
commit
713ab8fd29
2 changed files with 70 additions and 15 deletions
|
|
@ -127,27 +127,49 @@ class VertexBase:
|
|||
) -> tuple[_VertexCredentialsObject | None, str]:
|
||||
if credentials is not None:
|
||||
if isinstance(credentials, str):
|
||||
_is_path: Final = os.path.exists(
|
||||
credentials
|
||||
) # credentials is from server config (litellm_params), not user input
|
||||
verbose_logger.debug(
|
||||
"Vertex: Loading vertex credentials, is_file_path=%s, current dir %s",
|
||||
_is_path,
|
||||
"Vertex: Loading vertex credentials, current dir %s",
|
||||
os.getcwd(),
|
||||
)
|
||||
|
||||
try:
|
||||
if _is_path:
|
||||
# Decide by value shape, not os.path.exists(): exists()
|
||||
# swallows every OSError (missing, unreadable, transient),
|
||||
# which previously misreported all of them as invalid JSON.
|
||||
if credentials.lstrip().startswith("{"):
|
||||
try:
|
||||
json_obj = json.loads(credentials)
|
||||
except json.JSONDecodeError as e:
|
||||
raise Exception(
|
||||
"Unable to load vertex credentials from environment. "
|
||||
"Ensure the JSON is valid (check for unescaped newlines in private_key). "
|
||||
f"Parse error: {type(e).__name__}: {e}"
|
||||
) from e
|
||||
else:
|
||||
try:
|
||||
with open(credentials) as f:
|
||||
json_obj = json.load(f)
|
||||
else:
|
||||
json_obj = json.loads(credentials)
|
||||
except Exception as e:
|
||||
raise Exception(
|
||||
"Unable to load vertex credentials from environment. "
|
||||
"Ensure the JSON is valid (check for unescaped newlines in private_key). "
|
||||
f"Parse error: {type(e).__name__}"
|
||||
)
|
||||
except FileNotFoundError as e:
|
||||
raise Exception(
|
||||
"Unable to load vertex credentials from file path: "
|
||||
f"{credentials}. File not found. ({e})"
|
||||
) from e
|
||||
except PermissionError as e:
|
||||
raise Exception(
|
||||
"Unable to load vertex credentials from file path: "
|
||||
f"{credentials}. File not readable (permission denied). ({e})"
|
||||
) from e
|
||||
except OSError as e:
|
||||
raise Exception(
|
||||
"Unable to load vertex credentials from file path: "
|
||||
f"{credentials}. Unable to read file. ({e})"
|
||||
) from e
|
||||
except json.JSONDecodeError as e:
|
||||
raise Exception(
|
||||
"Unable to load vertex credentials from file path: "
|
||||
f"{credentials}. Ensure the JSON is valid "
|
||||
"(check for unescaped newlines in private_key). "
|
||||
f"Parse error: {type(e).__name__}: {e}"
|
||||
) from e
|
||||
elif isinstance(credentials, dict):
|
||||
json_obj = credentials
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -2193,3 +2193,36 @@ class TestVertexBase:
|
|||
|
||||
assert token == "cached-token"
|
||||
assert not mock_get_lock.called, "Fast path should not acquire lock"
|
||||
|
||||
|
||||
class TestLoadAuthCredentialFileErrors:
|
||||
def test_missing_credential_file_names_path(self):
|
||||
vertex_base = VertexBase()
|
||||
with pytest.raises(Exception, match="File not found"):
|
||||
vertex_base.load_auth(
|
||||
credentials="/nonexistent/vertexai.json", project_id="p"
|
||||
)
|
||||
|
||||
def test_unreadable_credential_file_names_path(self):
|
||||
vertex_base = VertexBase()
|
||||
with patch(
|
||||
"builtins.open", side_effect=PermissionError(13, "Permission denied")
|
||||
):
|
||||
with pytest.raises(Exception, match="not readable"):
|
||||
vertex_base.load_auth(
|
||||
credentials="/some/vertexai.json", project_id="p"
|
||||
)
|
||||
|
||||
def test_malformed_credential_file_keeps_json_advice(self, tmp_path):
|
||||
bad_file = tmp_path / "vertexai.json"
|
||||
bad_file.write_text("{not json")
|
||||
vertex_base = VertexBase()
|
||||
with pytest.raises(Exception, match="Ensure the JSON is valid"):
|
||||
vertex_base.load_auth(
|
||||
credentials=str(bad_file), project_id="p"
|
||||
)
|
||||
|
||||
def test_malformed_inline_json_keeps_environment_message(self):
|
||||
vertex_base = VertexBase()
|
||||
with pytest.raises(Exception, match="from environment"):
|
||||
vertex_base.load_auth(credentials="{not json", project_id="p")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue