Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix error message if invalid token on file download #2847

Merged
merged 1 commit into from
Feb 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/huggingface_hub/file_download.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
EntryNotFoundError,
FileMetadataError,
GatedRepoError,
HfHubHTTPError,
LocalEntryNotFoundError,
RepositoryNotFoundError,
RevisionNotFoundError,
Expand Down Expand Up @@ -1461,7 +1462,6 @@ def _get_metadata_or_catch_error(

def _raise_on_head_call_error(head_call_error: Exception, force_download: bool, local_files_only: bool) -> NoReturn:
"""Raise an appropriate error when the HEAD call failed and we cannot locate a local file."""

# No head call => we cannot force download.
if force_download:
if local_files_only:
Expand All @@ -1477,8 +1477,11 @@ def _raise_on_head_call_error(head_call_error: Exception, force_download: bool,
"Cannot find the requested files in the disk cache and outgoing traffic has been disabled. To enable"
" hf.co look-ups and downloads online, set 'local_files_only' to False."
)
elif isinstance(head_call_error, RepositoryNotFoundError) or isinstance(head_call_error, GatedRepoError):
elif isinstance(head_call_error, (RepositoryNotFoundError, GatedRepoError)) or (
isinstance(head_call_error, HfHubHTTPError) and head_call_error.response.status_code == 401
):
# Repo not found or gated => let's raise the actual error
# Unauthorized => likely a token issue => let's raise the actual error
raise head_call_error
else:
# Otherwise: most likely a connection issue or Hub downtime => let's warn the user
Expand Down
1 change: 1 addition & 0 deletions src/huggingface_hub/utils/_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,7 @@ def hf_raise_for_status(response: Response, endpoint_name: Optional[str] = None)

elif error_code == "RepoNotFound" or (
response.status_code == 401
and error_message != "Invalid credentials in Authorization header"
and response.request is not None
and response.request.url is not None
and REPO_API_REGEX.search(response.request.url) is not None
Expand Down
14 changes: 13 additions & 1 deletion tests/test_utils_errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def test_hf_raise_for_status_disabled_repo(self) -> None:
assert context.exception.response.status_code == 403
assert "Request ID: 123" in str(context.exception)

def test_hf_raise_for_status_401_repo_url(self) -> None:
def test_hf_raise_for_status_401_repo_url_not_invalid_token(self) -> None:
response = Response()
response.headers = {X_REQUEST_ID: 123}
response.status_code = 401
Expand All @@ -48,6 +48,18 @@ def test_hf_raise_for_status_401_repo_url(self) -> None:
assert context.exception.response.status_code == 401
assert "Request ID: 123" in str(context.exception)

def test_hf_raise_for_status_401_repo_url_invalid_token(self) -> None:
response = Response()
response.headers = {X_REQUEST_ID: 123, "X-Error-Message": "Invalid credentials in Authorization header"}
response.status_code = 401
response.request = PreparedRequest()
response.request.url = "https://huggingface.co/api/models/username/reponame"
with self.assertRaisesRegex(HfHubHTTPError, "Invalid credentials in Authorization header") as context:
hf_raise_for_status(response)

assert context.exception.response.status_code == 401
assert "Request ID: 123" in str(context.exception)

def test_hf_raise_for_status_403_wrong_token_scope(self) -> None:
response = Response()
response.headers = {X_REQUEST_ID: 123, "X-Error-Message": "specific error message"}
Expand Down
Loading