gRPC Error Handling Patterns in Protobuf
Design protobuf schemas for robust gRPC error handling. Covers status codes, error details, structured error responses, and the google.rpc.Status pattern.
Detailed Explanation
Structuring Errors in gRPC Services
gRPC uses numeric status codes for transport-level errors, but application-level errors often need richer information. Designing your protobuf schema to carry structured error details is a best practice for production services.
syntax = "proto3";
package api.v1;
import "google/protobuf/any.proto";
service OrderService {
rpc PlaceOrder(PlaceOrderRequest) returns (PlaceOrderResponse);
rpc CancelOrder(CancelOrderRequest) returns (CancelOrderResponse);
}
message PlaceOrderRequest {
string customer_id = 1;
repeated OrderItem items = 2;
PaymentInfo payment = 3;
}
message PlaceOrderResponse {
oneof result {
Order order = 1;
OrderError error = 2;
}
}
message OrderError {
ErrorCode code = 1;
string message = 2;
repeated FieldViolation field_violations = 3;
map<string, string> metadata = 4;
}
enum ErrorCode {
ERROR_CODE_UNSPECIFIED = 0;
ERROR_CODE_INVALID_INPUT = 1;
ERROR_CODE_OUT_OF_STOCK = 2;
ERROR_CODE_PAYMENT_DECLINED = 3;
ERROR_CODE_CUSTOMER_NOT_FOUND = 4;
ERROR_CODE_RATE_LIMITED = 5;
}
message FieldViolation {
string field = 1;
string description = 2;
}
message OrderItem {
string product_id = 1;
int32 quantity = 2;
}
message PaymentInfo {
string method = 1;
string token = 2;
}
message Order {
string order_id = 1;
string status = 2;
double total = 3;
}
message CancelOrderRequest {
string order_id = 1;
string reason = 2;
}
message CancelOrderResponse {
bool success = 1;
}
Error Handling Strategies
Strategy 1: Oneof in response (shown above) — The response contains either a success payload or an error object. The client checks which variant is set. This keeps error details in-band and typed.
Strategy 2: gRPC Status with details — Return a gRPC error status and attach structured detail messages using google.rpc.Status and google.protobuf.Any. This follows Google's error model.
Strategy 3: Error fields in response — Include optional error fields alongside the normal response. The presence of an error field indicates failure.
Best Practices
- Define domain-specific error codes as enums
- Include machine-readable error codes for programmatic handling
- Include human-readable messages for logging and debugging
- Use
FieldViolationfor validation errors to identify exactly which fields are invalid - Version your error types alongside your service to maintain compatibility
Use Case
Designing production gRPC APIs that need structured, parseable error responses for input validation failures, business rule violations, and operational errors across microservices.