GoogleCloudPlatform/microservices-demo · error
could not convert currency for product #
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.
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
- could not retrieve product #
- failed to add to cart
- failed to convert currency
- failed to empty cart
- could not retrieve cart
AI-assisted analysis of GoogleCloudPlatform/microservices-demo@72ba613a05 (2026-09-02).
Data as JSON: /api/errors/47bbbed9402944f6.
Report an issue: GitHub.
Appendix: 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)