Skip to content

Commit afc135c

Browse files
committed
Add a GrpcStatusError subclass for unrecognized status codes
When we receive a gRPC status code that we don't recognize, we raise a `GrpcStatusError` instead of the base class for all gRPC status errors. This will allow users to more easily differentiate between known and unknown status codes. Signed-off-by: Leandro Lucarella <[email protected]>
1 parent fb46558 commit afc135c

File tree

3 files changed

+33
-15
lines changed

3 files changed

+33
-15
lines changed

src/frequenz/client/microgrid/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
ResourceExhausted,
4747
ServiceUnavailable,
4848
UnknownError,
49+
UnrecognizedGrpcStatus,
4950
)
5051
from ._metadata import Location, Metadata
5152

@@ -87,4 +88,5 @@
8788
"ResourceExhausted",
8889
"ServiceUnavailable",
8990
"UnknownError",
91+
"UnrecognizedGrpcStatus",
9092
]

src/frequenz/client/microgrid/_exception.py

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,13 @@ def from_grpc_error(
5858
server_url: str,
5959
operation: str,
6060
grpc_error: grpclib.GRPCError,
61-
retryable: bool = True,
6261
) -> GrpcStatusError:
6362
"""Create an instance of the appropriate subclass from a gRPC error.
6463
6564
Args:
6665
server_url: The URL of the server that returned the error.
6766
operation: The operation that caused the error.
6867
grpc_error: The gRPC error to convert.
69-
retryable: Whether retrying the operation might succeed.
7068
7169
Returns:
7270
An instance of
@@ -104,12 +102,10 @@ def __call__(
104102
return ctor(
105103
server_url=server_url, operation=operation, grpc_error=grpc_error
106104
)
107-
return GrpcStatusError(
105+
return UnrecognizedGrpcStatus(
108106
server_url=server_url,
109107
operation=operation,
110-
description="Got an unrecognized status code",
111108
grpc_error=grpc_error,
112-
retryable=retryable,
113109
)
114110

115111

@@ -156,6 +152,28 @@ def __init__( # pylint: disable=too-many-arguments
156152
"""The original gRPC error."""
157153

158154

155+
class UnrecognizedGrpcStatus(GrpcStatusError):
156+
"""The gRPC server returned an unrecognized status code."""
157+
158+
def __init__(
159+
self, *, server_url: str, operation: str, grpc_error: grpclib.GRPCError
160+
) -> None:
161+
"""Create a new instance.
162+
163+
Args:
164+
server_url: The URL of the server that returned the error.
165+
operation: The operation that caused the error.
166+
grpc_error: The gRPC error originating this exception.
167+
"""
168+
super().__init__(
169+
server_url=server_url,
170+
operation=operation,
171+
description="Got an unrecognized status code",
172+
grpc_error=grpc_error,
173+
retryable=True, # We don't know so we assume it's retryable
174+
)
175+
176+
159177
class OperationCancelled(GrpcStatusError):
160178
"""The operation was cancelled."""
161179

tests/test_exception.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
ResourceExhausted,
3030
ServiceUnavailable,
3131
UnknownError,
32+
UnrecognizedGrpcStatus,
3233
)
3334

3435

@@ -41,6 +42,12 @@ def __call__(
4142

4243

4344
ERROR_TUPLES: list[tuple[type[GrpcStatusError], grpclib.Status, str, bool]] = [
45+
(
46+
UnrecognizedGrpcStatus,
47+
mock.MagicMock(name="unknown_status"),
48+
"Got an unrecognized status code",
49+
True,
50+
),
4451
(
4552
OperationCancelled,
4653
grpclib.Status.CANCELLED,
@@ -200,16 +207,7 @@ def test_client_error() -> None:
200207

201208

202209
@pytest.mark.parametrize(
203-
"exception_class, grpc_status, expected_description, retryable",
204-
ERROR_TUPLES
205-
+ [
206-
(
207-
GrpcStatusError,
208-
mock.MagicMock(name="unknown_status"),
209-
"Got an unrecognized status code",
210-
True,
211-
)
212-
],
210+
"exception_class, grpc_status, expected_description, retryable", ERROR_TUPLES
213211
)
214212
def test_from_grpc_error(
215213
exception_class: type[GrpcStatusError],

0 commit comments

Comments
 (0)