Error Handling & Metadata
🚦 Error Handling & Metadata
gRPC Status Codes vs. HTTP Status Codes
gRPC has its own fixed enum of status codes, purpose-built for RPC semantics — distinct from HTTP's status codes, even though gRPC calls physically ride on top of HTTP/2.
HTTP Status Codes vs. gRPC Status Codes
HTTP
~40 general-purpose codes designed for web resources and REST conventions (404, 401, 500...).
gRPC
A fixed set of ~17 codes designed specifically for RPC outcomes — several (like DEADLINE_EXCEEDED or ALREADY_EXISTS) have no clean HTTP equivalent at all.
| gRPC Status Code | Meaning |
|---|---|
OK | The call succeeded |
INVALID_ARGUMENT | The request itself was malformed |
NOT_FOUND | The requested resource doesn't exist |
ALREADY_EXISTS | An attempt to create something that already exists |
PERMISSION_DENIED | Authenticated, but not authorized for this action |
UNAUTHENTICATED | No valid credentials were provided at all |
DEADLINE_EXCEEDED | The call didn't complete before its deadline |
UNAVAILABLE | The service is temporarily unreachable — often safe to retry |
INTERNAL | An unexpected server-side error |
Rich Error Details
Beyond a status code and a message, gRPC supports attaching structured error details via the google.rpc.Status extension mechanism — field-level validation errors, retry-after hints, or any custom structured data, all still strongly typed via Protobuf rather than the ad-hoc, differently-shaped error JSON bodies common across different REST APIs.
Metadata
Metadata is gRPC's equivalent of HTTP headers — key-value pairs sent alongside a call, outside the message body itself. Common uses: auth tokens (Chapter 7 covers this properly), request tracing IDs, and custom routing hints.
Deadlines & Timeouts
Every gRPC call should carry a deadline — an absolute point in time by which the call must complete, after which it's automatically cancelled with DEADLINE_EXCEEDED. Deadlines are more powerful than a plain client-side timeout: they propagate across a chain of calls. If Service A calls Service B, which calls Service C, the same deadline can flow through all three — a slow Service C doesn't leave Service A waiting indefinitely, because the whole chain shares one clock, directly relevant to Chapter 8's microservices coverage.
💻 Coding Challenges
Challenge 1: Pick the Right Status Code
For each, name the correct gRPC status code: (a) a client requests a product ID that doesn't exist, (b) a client sends a request with no auth token at all, (c) a downstream service is temporarily down and the call couldn't be completed.
Goal: Practice matching a concrete failure to its specific gRPC status code, not just a generic "error."
Challenge 2: Explain Deadline Propagation
Service A calls Service B, which calls Service C. Explain, using this chapter's material, what deadline propagation buys this chain that a plain timeout set independently at each hop wouldn't.
Goal: Practice explaining why a shared deadline across a call chain is a genuine architectural advantage, not just a convenience.
Challenge 3: Metadata or Message Field?
For each, say whether it belongs in gRPC metadata or as a field in the request message: (a) an auth token, (b) the product ID being requested, (c) a request-tracing ID used for logging across services.
Goal: Practice distinguishing data that's genuinely part of the call's payload from auxiliary data that travels alongside it.
Because gRPC rides on top of HTTP/2, a call's underlying HTTP status is very often 200 regardless of whether the gRPC call itself succeeded — the real outcome is communicated separately, via gRPC's own status field sent in an HTTP/2 trailer. Code that checks only the HTTP-level response (natural habit coming from REST) can easily miss a genuine NOT_FOUND or INTERNAL failure entirely. Always check the gRPC status specifically — generated client stubs surface this through the language's own error/exception mechanism (as in this chapter's err.code example), not through an HTTP status code. Relatedly, deadline propagation is typically opt-in per language/library, not automatic just because a deadline was set on the outermost call — check the specific gRPC library's documentation for how it actually threads a deadline through nested calls.
🎯 What's Next
The next chapter is Interceptors & Middleware — client/server interceptors for logging, auth, and retries, the gRPC equivalent of Express middleware.