GoogleCloudPlatform/microservices-demo · error

could not retrieve cart

Error message

could not retrieve cart

What it means

homeHandler fetches the user's cart via fe.getCart (gRPC CartService.GetCart) using the session id. On error it wraps with errors.Wrap(err, "could not retrieve cart") and renders HTTP 500. The home page needs the cart to show item counts, so a cart service failure blocks rendering.

Source

Thrown at src/frontend/handlers.go:74

var validEnvs = []string{"local", "gcp", "azure", "aws", "onprem", "alibaba"}

func (fe *frontendServer) homeHandler(w http.ResponseWriter, r *http.Request) {
	log := r.Context().Value(ctxKeyLog{}).(logrus.FieldLogger)
	log.WithField("currency", currentCurrency(r)).Info("home")
	currencies, err := fe.getCurrencies(r.Context())
	if err != nil {
		renderHTTPError(log, r, w, errors.Wrap(err, "could not retrieve currencies"), http.StatusInternalServerError)
		return
	}
	products, err := fe.getProducts(r.Context())
	if err != nil {
		renderHTTPError(log, r, w, errors.Wrap(err, "could not retrieve products"), http.StatusInternalServerError)
		return
	}
	cart, err := fe.getCart(r.Context(), sessionID(r))
	if err != nil {
		renderHTTPError(log, r, w, errors.Wrap(err, "could not retrieve cart"), http.StatusInternalServerError)
		return
	}

	type productView struct {
		Item  *pb.Product
		Price *pb.Money
	}
	ps := make([]productView, len(products))
	for i, p := range products {
		price, err := fe.convertCurrency(r.Context(), p.GetPriceUsd(), currentCurrency(r))
		if err != nil {
			renderHTTPError(log, r, w, errors.Wrapf(err, "failed to do currency conversion for product %s", p.GetId()), http.StatusInternalServerError)
			return
		}
		ps[i] = productView{p, price}
	}

	// Set ENV_PLATFORM (default to local if not set; use env var if set; otherwise detect GCP, which overrides env)_

View on GitHub (pinned to 72ba613a05)

Solutions

  1. Check cart service health and its backing store (e.g. Redis) connectivity
  2. Verify CART_SERVICE_ADDR configuration
  3. Confirm a valid session/user id exists before calling getCart; treat empty session as an empty cart
  4. Inspect the wrapped cause for the gRPC status code (Unavailable vs InvalidArgument)
  5. Consider degrading gracefully (render page with empty cart) instead of 500

Example fix

// before
cart, err := fe.getCart(r.Context(), sessionID(r))
if err != nil {
    renderHTTPError(log, r, w, errors.Wrap(err, "could not retrieve cart"), http.StatusInternalServerError)
    return
}
// after
cart, err := fe.getCart(r.Context(), sessionID(r))
if err != nil {
    log.WithError(err).Warn("could not retrieve cart, showing empty cart")
    cart = &pb.Cart{}
}
Defensive patterns

Strategy: fallback

Validate before calling

userID := sessionID(r)
if userID == "" {
    cart = &pb.Cart{}
    // skip GetCart entirely
}

Try / catch

cart, err := fe.getCart(r.Context(), sessionID(r))
if err != nil {
    log.WithError(err).Warn("cart unavailable, rendering empty cart")
    cart = &pb.Cart{}
}

Prevention

When it happens

Trigger: fe.getCart(r.Context(), sessionID(r)) returns error: cart service unavailable, RPC deadline, invalid/empty user/session id passed to GetCart, or cart service returning an error status.

Common situations: Cart service (often Redis-backed) down or its Redis unreachable; CART_SERVICE_ADDR wrong; session cookie missing causing empty user id; network policy blocking frontend→cart traffic.

Related errors


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