Errors
Similar to the familiar “404 Not Found” and “500 Internal Server Error” status codes in HTTP, Connect uses a set of 16 error codes. These error codes are designed to work consistently across Connect, gRPC, and gRPC-Web protocols.
Working with errors
Section titled “Working with errors”Connect handlers raise errors using ConnectError:
from connectrpc.code import Codefrom connectrpc.errors import ConnectErrorfrom connectrpc.request import RequestContext
async def greet(self, request: GreetRequest, ctx: RequestContext) -> GreetResponse: if not request.name: raise ConnectError(Code.INVALID_ARGUMENT, "name is required") return GreetResponse(greeting=f"Hello, {request.name}!")from connectrpc.code import Codefrom connectrpc.errors import ConnectErrorfrom connectrpc.request import RequestContext
def greet(self, request: GreetRequest, ctx: RequestContext) -> GreetResponse: if not request.name: raise ConnectError(Code.INVALID_ARGUMENT, "name is required") return GreetResponse(greeting=f"Hello, {request.name}!")Clients catch errors the same way:
from connectrpc.code import Codefrom connectrpc.errors import ConnectError
async with GreetServiceClient("http://localhost:8000") as client: try: response = await client.greet(GreetRequest(name="")) except ConnectError as e: if e.code == Code.INVALID_ARGUMENT: print(f"Invalid request: {e.message}") else: print(f"RPC failed: {e.code} - {e.message}")from connectrpc.code import Codefrom connectrpc.errors import ConnectError
with GreetServiceClientSync("http://localhost:8000") as client: try: response = client.greet(GreetRequest(name="")) except ConnectError as e: if e.code == Code.INVALID_ARGUMENT: print(f"Invalid request: {e.message}") else: print(f"RPC failed: {e.code} - {e.message}")Error codes
Section titled “Error codes”Connect uses a set of 16 error codes. The code property of a ConnectError holds one of these codes. All error codes are available through the Code enumeration:
from connectrpc.code import Code
code = Code.INVALID_ARGUMENTcode.value # "invalid_argument"
# Access by nameCode["INVALID_ARGUMENT"] # Code.INVALID_ARGUMENTError messages
Section titled “Error messages”The message property contains a descriptive error message. In most cases, the message is provided by the backend implementing the service:
try: response = await client.greet(GreetRequest(name=""))except ConnectError as e: print(e.message) # "name is required"Error details
Section titled “Error details”Errors can include strongly-typed details using Protobuf messages:
from connectrpc.code import Codefrom connectrpc.errors import ConnectErrorfrom connectrpc.request import RequestContextfrom google.protobuf.struct_pb2 import Struct, Value
async def create_user(self, request: CreateUserRequest, ctx: RequestContext) -> CreateUserResponse: if not request.email: error_detail = Struct(fields={ "field": Value(string_value="email"), "issue": Value(string_value="Email is required") })
raise ConnectError( Code.INVALID_ARGUMENT, "Invalid user request", details=[error_detail] ) # ... rest of implementationReading error details on the client
Section titled “Reading error details on the client”Error details are google.protobuf.Any messages that can be unpacked to their original types:
try: response = await client.some_method(request)except ConnectError as e: for detail in e.details: # Check the type before unpacking if detail.Is(Struct.DESCRIPTOR): unpacked = Struct() detail.Unpack(unpacked) print(f"Error detail: {unpacked}")Standard error detail types
Section titled “Standard error detail types”With googleapis-common-protos installed, you can use standard types like:
BadRequest: Field violations in a requestRetryInfo: When to retryHelp: Links to documentationQuotaFailure: Quota violationsErrorInfo: Structured error metadata
Example:
from google.rpc.error_details_pb2 import BadRequest
bad_request = BadRequest()violation = bad_request.field_violations.add()violation.field = "email"violation.description = "Must be a valid email address"
raise ConnectError( Code.INVALID_ARGUMENT, "Invalid email format", details=[bad_request])HTTP representation
Section titled “HTTP representation”In the Connect protocol, errors are always JSON:
HTTP/1.1 400 Bad RequestContent-Type: application/json
{ "code": "invalid_argument", "message": "name is required", "details": [ { "type": "google.protobuf.Struct", "value": "base64-encoded-protobuf", "debug": {"field": "email", "issue": "Email is required"} } ]}See the Connect protocol for a full description
of the error detail fields, including type, value, and debug.
See also
Section titled “See also”- Interceptors for error transformation and logging
- Streaming for stream-specific error handling
- Headers and trailers for attaching metadata to errors