Skip to content

Commit 9b73ddf

Browse files
committed
fix
Signed-off-by: i2y <6240399+i2y@users.noreply.github.com>
1 parent 21f3980 commit 9b73ddf

File tree

1 file changed

+57
-17
lines changed

1 file changed

+57
-17
lines changed

docs/errors.md

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
Connect uses a standard set of error codes to indicate what went wrong with an RPC. Each error includes a `Code`, a human-readable message, and optionally some typed error details. This document explains how to work with errors in connect-python.
44

5+
For streaming RPCs, error handling has some special considerations - see the [streaming documentation](streaming.md) for details. You can also attach error information to headers and trailers - see the [headers and trailers documentation](headers-and-trailers.md).
6+
57
## Error codes
68

79
Connect defines 16 error codes. Each code maps to a specific HTTP status code when using the Connect protocol over HTTP. The full list of codes is available in the `connectrpc.code.Code` enum:
@@ -74,14 +76,14 @@ When a client receives an error response, the client stub raises a `ConnectError
7476
from greet.v1.greet_pb2 import GreetRequest
7577

7678
async def main():
77-
client = GreetServiceClient("http://localhost:8000")
78-
try:
79-
response = await client.greet(GreetRequest(name=""))
80-
except ConnectError as e:
81-
if e.code == Code.INVALID_ARGUMENT:
82-
print(f"Invalid request: {e.message}")
83-
else:
84-
print(f"RPC failed: {e.code} - {e.message}")
79+
async with GreetServiceClient("http://localhost:8000") as client:
80+
try:
81+
response = await client.greet(GreetRequest(name=""))
82+
except ConnectError as e:
83+
if e.code == Code.INVALID_ARGUMENT:
84+
print(f"Invalid request: {e.message}")
85+
else:
86+
print(f"RPC failed: {e.code} - {e.message}")
8587
```
8688

8789
=== "Sync"
@@ -93,14 +95,14 @@ When a client receives an error response, the client stub raises a `ConnectError
9395
from greet.v1.greet_pb2 import GreetRequest
9496

9597
def main():
96-
client = GreetServiceClientSync("http://localhost:8000")
97-
try:
98-
response = client.greet(GreetRequest(name=""))
99-
except ConnectError as e:
100-
if e.code == Code.INVALID_ARGUMENT:
101-
print(f"Invalid request: {e.message}")
102-
else:
103-
print(f"RPC failed: {e.code} - {e.message}")
98+
with GreetServiceClientSync("http://localhost:8000") as client:
99+
try:
100+
response = client.greet(GreetRequest(name=""))
101+
except ConnectError as e:
102+
if e.code == Code.INVALID_ARGUMENT:
103+
print(f"Invalid request: {e.message}")
104+
else:
105+
print(f"RPC failed: {e.code} - {e.message}")
104106
```
105107

106108
Client-side errors (like network failures, timeouts, or protocol violations) are also raised as `ConnectError` instances with appropriate error codes.
@@ -206,6 +208,44 @@ except ConnectError as e:
206208
print(f"Struct detail: {unpacked}")
207209
```
208210

211+
#### Understanding google.protobuf.Any
212+
213+
The `google.protobuf.Any` type stores arbitrary protobuf messages along with their type information. Key properties:
214+
215+
- `type_url`: A string identifying the message type (e.g., `type.googleapis.com/google.protobuf.Struct`)
216+
- `value`: The serialized bytes of the actual message
217+
218+
Debugging tips:
219+
220+
```python
221+
try:
222+
response = await client.some_method(request)
223+
except ConnectError as e:
224+
for detail in e.details:
225+
# Inspect the type URL to understand what type this detail is
226+
print(f"Detail type: {detail.type_url}")
227+
228+
# Try unpacking with the expected type
229+
if "Struct" in detail.type_url:
230+
unpacked = Struct()
231+
if detail.Unpack(unpacked):
232+
print(f"Struct content: {unpacked}")
233+
elif "BadRequest" in detail.type_url:
234+
from google.rpc.error_details_pb2 import BadRequest
235+
unpacked = BadRequest()
236+
if detail.Unpack(unpacked):
237+
for violation in unpacked.field_violations:
238+
print(f"Field: {violation.field}, Error: {violation.description}")
239+
```
240+
241+
Common issues and solutions:
242+
243+
1. **Type mismatch**: If `Unpack()` returns `False`, the message type doesn't match. Check the `type_url` to see the actual type.
244+
245+
2. **Missing proto imports**: Ensure you've imported the correct protobuf message classes for the error details you expect to receive.
246+
247+
3. **Custom error details**: If using custom protobuf messages for error details, ensure both client and server have access to the same proto definitions.
248+
209249
### Common error detail types
210250

211251
You can use any protobuf message type for error details. Some commonly used types include:
@@ -251,7 +291,7 @@ raise ConnectError(
251291

252292
## Error handling in interceptors
253293

254-
Interceptors can catch and transform errors. This is useful for adding context, converting error types, or implementing retry logic:
294+
Interceptors can catch and transform errors. This is useful for adding context, converting error types, or implementing retry logic. For more details on interceptors, see the [interceptors documentation](interceptors.md):
255295

256296
=== "ASGI"
257297

0 commit comments

Comments
 (0)