GoogleCloudPlatform/microservices-demo · error

could not convert currency for product #%s

Error message

could not convert currency for product #%s

What it means

While building the cart item views, viewCartHandler failed to convert a product's USD price to the selected currency via fe.convertCurrency. The error uses errors.Wrapf with the product ID and is rendered as HTTP 500, aborting the cart page render.

Source

Thrown at src/frontend/handlers.go:292

		return
	}

	type cartItemView struct {
		Item     *pb.Product
		Quantity int32
		Price    *pb.Money
	}
	items := make([]cartItemView, len(cart))
	totalPrice := pb.Money{CurrencyCode: currentCurrency(r)}
	for i, item := range cart {
		p, err := fe.getProduct(r.Context(), item.GetProductId())
		if err != nil {
			renderHTTPError(log, r, w, errors.Wrapf(err, "could not retrieve product #%s", item.GetProductId()), http.StatusInternalServerError)
			return
		}
		price, err := fe.convertCurrency(r.Context(), p.GetPriceUsd(), currentCurrency(r))
		if err != nil {
			renderHTTPError(log, r, w, errors.Wrapf(err, "could not convert currency for product #%s", item.GetProductId()), http.StatusInternalServerError)
			return
		}

		multPrice := money.MultiplySlow(*price, uint32(item.GetQuantity()))
		items[i] = cartItemView{
			Item:     p,
			Quantity: item.GetQuantity(),
			Price:    &multPrice}
		totalPrice = money.Must(money.Sum(totalPrice, multPrice))
	}
	totalPrice = money.Must(money.Sum(totalPrice, *shippingCost))
	year := time.Now().Year()

	if err := templates.ExecuteTemplate(w, "cart", injectCommonTemplateData(r, map[string]interface{}{
		"currencies":       currencies,
		"recommendations":  recommendations,
		"cart_size":        cartSize(cart),
		"shipping_cost":    shippingCost,

View on GitHub (pinned to 72ba613a05)

Solutions

  1. Check currencyservice health and logs.
  2. Validate currentCurrency against supported currencies before the loop.
  3. Convert all prices in a single batch or cache conversions per request.
  4. Fall back to USD price with a warning instead of returning HTTP 500.

Example fix

// before
price, err := fe.convertCurrency(r.Context(), p.GetPriceUsd(), currentCurrency(r))
if err != nil {
    renderHTTPError(log, r, w, errors.Wrapf(err, "could not convert currency for product #%s", item.GetProductId()), http.StatusInternalServerError)
// after
price, err := fe.convertCurrency(r.Context(), p.GetPriceUsd(), currentCurrency(r))
if err != nil {
    log.WithField("product", item.GetProductId()).WithField("error", err).Warn("currency conversion failed, using USD")
    usdPrice := p.GetPriceUsd()
    price = &usdPrice
Defensive patterns

Strategy: fallback

Validate before calling

if !supportedCurrency(currentCurrency(r), supportedCurrencies) {
    log.Warn("unsupported currency in cookie; will fall back to USD")
}

Type guard

func supportedCurrency(code string, list []*pb.Currency) bool {
    for _, c := range list { if code == c.Code { return true } }
    return false
}

Try / catch

price, err := fe.convertCurrency(r.Context(), p.GetPriceUsd(), currentCurrency(r))
if err != nil {
    log.WithField("product", item.GetProductId()).WithField("error", err).Warn("conversion failed, using USD")
    usd := p.GetPriceUsd(); price = &usd
}

Prevention

When it happens

Trigger: GET /cart when currencyservice Convert fails for any cart item's price: currencyservice down, unsupported currency code from the user's cookie, or context canceled mid-loop.

Common situations: currencyservice outage, invalid/stale currency cookie value, per-request deadline exhausted because conversion fails on an early item in the loop.

Related errors


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