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
- Check currencyservice health and logs.
- Validate currentCurrency against supported currencies before the loop.
- Convert all prices in a single batch or cache conversions per request.
- 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
- Fall back to USD pricing on conversion failure.
- Validate currency cookies against the supported list.
- Cache conversions per request to avoid repeated failing RPCs.
- Alert on currencyservice Convert error rates.
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
- failed to convert currency
- failed to add to cart
- failed to empty cart
- could not retrieve product #%s
- failed to convert shipping cost to currency: %+v
AI-assisted analysis of GoogleCloudPlatform/microservices-demo@72ba613a05 (2026-09-02).
Data as JSON: /api/errors/47bbbed9402944f6.
Report an issue: GitHub.