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

  1. Check the wrapped error: if it is 'failed to get product', verify the product ID exists via ProductCatalogService.ListProducts.
  2. Ensure the productcatalogservice deployment is healthy: kubectl get pods, check its logs and readiness probes.
  3. Verify the user's currency code is one supported by currencyservice (see pb getSupportedCurrencies).
  4. 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

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


AI-assisted analysis of GoogleCloudPlatform/microservices-demo@72ba613a05 (2026-09-02). Data as JSON: /api/errors/bde57489f9d7d1f2. Report an issue: GitHub.