GoogleCloudPlatform/microservices-demo · error
failed to prepare order: %+v
Error message
failed to prepare order: %+v
What it means
prepareOrderItemsAndShippingQuoteFromCart wraps any error from prepOrderItems (which fetches products from the product catalog and converts their prices) with this message before bubbling it up to PlaceOrder. It is a pass-through wrapper: the root cause is always a downstream product-catalog or currency-conversion failure. The %+v verb unwraps the wrapped error chain for diagnostics.
Source
Thrown at src/checkoutservice/main.go:296
resp := &pb.PlaceOrderResponse{Order: orderResult}
return resp, nil
}
type orderPrep struct {
orderItems []*pb.OrderItem
cartItems []*pb.CartItem
shippingCostLocalized *pb.Money
}
func (cs *checkoutService) prepareOrderItemsAndShippingQuoteFromCart(ctx context.Context, userID, userCurrency string, address *pb.Address) (orderPrep, error) {
var out orderPrep
cartItems, err := cs.getUserCart(ctx, userID)
if err != nil {
return out, fmt.Errorf("cart failure: %+v", err)
}
orderItems, err := cs.prepOrderItems(ctx, cartItems, userCurrency)
if err != nil {
return out, fmt.Errorf("failed to prepare order: %+v", err)
}
shippingUSD, err := cs.quoteShipping(ctx, address, cartItems)
if err != nil {
return out, fmt.Errorf("shipping quote failure: %+v", err)
}
shippingPrice, err := cs.convertCurrency(ctx, shippingUSD, userCurrency)
if err != nil {
return out, fmt.Errorf("failed to convert shipping cost to currency: %+v", err)
}
out.shippingCostLocalized = shippingPrice
out.cartItems = cartItems
out.orderItems = orderItems
return out, nil
}
func (cs *checkoutService) quoteShipping(ctx context.Context, address *pb.Address, items []*pb.CartItem) (*pb.Money, error) {
shippingQuote, err := pb.NewShippingServiceClient(cs.shippingSvcConn).View on GitHub (pinned to 72ba613a05)
Solutions
- Check the wrapped error: if it is 'failed to get product', verify the product ID exists via ProductCatalogService.ListProducts.
- Ensure the productcatalogservice deployment is healthy: kubectl get pods, check its logs and readiness probes.
- Verify the user's currency code is one supported by currencyservice (see pb getSupportedCurrencies).
- Confirm network policies/DNS allow checkoutservice to reach productcatalogservice and currencyservice on gRPC ports.
Example fix
// before
orderItems, err := cs.prepOrderItems(ctx, cartItems, userCurrency)
if err != nil {
return out, fmt.Errorf("failed to prepare order: %+v", err)
}
// after
orderItems, err := cs.prepOrderItems(ctx, cartItems, userCurrency)
if err != nil {
log.Printf("prepOrderItems failed for user %s: %v", userID, err)
return out, fmt.Errorf("failed to prepare order: %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
// Go: validate cart and currency before calling PlaceOrder
if len(cartItems) == 0 {
return status.Error(codes.FailedPrecondition, "cart is empty")
}
if !isSupportedCurrency(userCurrency) {
return status.Error(codes.InvalidArgument, "unsupported currency: "+userCurrency)
} Type guard
func isSupportedCurrency(code string) bool {
for _, c := range supportedCurrencies { // fetched from currencyservice at startup
if c == code {
return true
}
}
return false
} Try / catch
orderItems, err := cs.prepareOrderItemsAndShippingQuoteFromCart(ctx, order, userID, userCurrency, address)
if err != nil {
var gerr *grpcStatusError
if errors.As(err, &gerr) && status.Code(gerr) == codes.Unavailable {
// retry with backoff or return 503
}
return fmt.Errorf("checkout failed: %w", err)
} Prevention
- Validate cart item IDs against the catalog before checkout
- Verify the target currency is supported before conversion
- Keep gRPC connections health-checked; enable retry policy on the channel
- Wrap errors with %w so root causes stay visible in logs
When it happens
Trigger: prepOrderItems fails because ProductCatalogService.GetProduct returns an error for one of the cart item IDs (unknown/missing product, catalog RPC failure), or convertCurrency fails for a product price (currency service down, unsupported currency code).
Common situations: Stale cart entries pointing at product IDs that no longer exist in the catalog; product-catalog service crashed or unreachable in Kubernetes; user currency code unsupported by the currency service; network policy blocking checkout->catalog gRPC traffic.
Related errors
- cart failure: %+v
- could not charge the card: %+v
- shipment failed: %+v
- shipping quote failure: %+v
- failed to convert shipping cost to currency: %+v
AI-assisted analysis of GoogleCloudPlatform/microservices-demo@72ba613a05 (2026-09-02).
Data as JSON: /api/errors/bde57489f9d7d1f2.
Report an issue: GitHub.