Skip to content
Open
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
18 changes: 14 additions & 4 deletions packages/google-api-core/google/api_core/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,11 @@
on :mod:`google.api_core`, including both HTTP and gRPC clients.
"""

from __future__ import absolute_import
from __future__ import unicode_literals
from __future__ import absolute_import, unicode_literals

import http.client
from typing import Optional, Dict
import warnings
from typing import Dict, Optional

from google.rpc import error_details_pb2

Expand Down Expand Up @@ -657,9 +656,20 @@ def from_grpc_error(rpc_exc):
grpc is not None and isinstance(rpc_exc, grpc.Call)
) or _is_informative_grpc_error(rpc_exc):
details, err_info = _parse_grpc_error_details(rpc_exc)
message = rpc_exc.details()
if (
grpc is not None
and rpc_exc.code() == grpc.StatusCode.UNIMPLEMENTED
and "Received http2 header with status: 404" in message
):
message = (
f"{message}. This usually indicates that the 'api_endpoint' "
"configuration in ClientOptions is incorrect, contains a typo, "
"or is an invalid regional endpoint for this service."
)
return from_grpc_status(
rpc_exc.code(),
rpc_exc.details(),
message,
errors=(rpc_exc,),
details=details,
response=rpc_exc,
Expand Down
18 changes: 17 additions & 1 deletion packages/google-api-core/tests/unit/test_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@
except ImportError: # pragma: NO COVER
grpc = rpc_status = None

from google.api_core import exceptions
from google.protobuf import any_pb2, json_format
from google.rpc import error_details_pb2, status_pb2

from google.api_core import exceptions


def test_create_google_cloud_error():
exception = exceptions.GoogleAPICallError("Testing")
Expand Down Expand Up @@ -393,3 +394,18 @@ def test_error_details_from_grpc_response_unknown_error():
and exception.domain is None
and exception.metadata is None
)


@pytest.mark.skipif(grpc is None, reason="No grpc")
def test_from_grpc_error_misleading_404():
message = "Received http2 header with status: 404"
error = mock.create_autospec(grpc.Call, instance=True)
error.code.return_value = grpc.StatusCode.UNIMPLEMENTED
error.details.return_value = message

exception = exceptions.from_grpc_error(error)

assert isinstance(exception, exceptions.MethodNotImplemented)
assert exception.grpc_status_code == grpc.StatusCode.UNIMPLEMENTED
assert "Received http2 header with status: 404" in exception.message
assert "api_endpoint" in exception.message
Loading