GoogleCloudPlatform/microservices-demo · error

failed to convert currency

Error message

failed to convert currency

What it means

The productHandler failed to convert the product's USD price into the user's selected currency via fe.convertCurrency (currencyservice Convert RPC). The error is wrapped and rendered as an HTTP 500 page. It means the currency conversion RPC failed or the currency code is invalid.

Source

Thrown at src/frontend/handlers.go:173

	if err != nil {
		renderHTTPError(log, r, w, errors.Wrap(err, "could not retrieve product"), http.StatusInternalServerError)
		return
	}
	currencies, err := fe.getCurrencies(r.Context())
	if err != nil {
		renderHTTPError(log, r, w, errors.Wrap(err, "could not retrieve currencies"), 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
	}

	price, err := fe.convertCurrency(r.Context(), p.GetPriceUsd(), currentCurrency(r))
	if err != nil {
		renderHTTPError(log, r, w, errors.Wrap(err, "failed to convert currency"), http.StatusInternalServerError)
		return
	}

	// ignores the error retrieving recommendations since it is not critical
	recommendations, err := fe.getRecommendations(r.Context(), sessionID(r), []string{id})
	if err != nil {
		log.WithField("error", err).Warn("failed to get product recommendations")
	}

	product := struct {
		Item  *pb.Product
		Price *pb.Money
	}{p, price}

	// Fetch packaging info (weight/dimensions) of the product
	// The packaging service is an optional microservice you can run as part of a Google Cloud demo.
	var packagingInfo *PackagingInfo = nil
	if isPackagingServiceConfigured() {

View on GitHub (pinned to 72ba613a05)

Solutions

  1. Check currencyservice availability and its logs.
  2. Validate the currentCurrency value against fe.getCurrencies() before converting.
  3. Clear/fix the user's currency cookie to a supported code.
  4. Increase timeouts or check network connectivity to currencyservice.

Example fix

// before
price, err := fe.convertCurrency(ctx, p.GetPriceUsd(), currentCurrency(r))
// after
supported, _ := fe.getCurrencies(ctx)
if !containsCurrency(supported, currentCurrency(r)) {
    log.Warn("unsupported currency, falling back to USD")
}
price, err := fe.convertCurrency(ctx, p.GetPriceUsd(), currentCurrency(r))
Defensive patterns

Strategy: validation

Validate before calling

supported, err := fe.getCurrencies(ctx)
if err == nil && !containsCurrency(supported, currentCurrency(r)) {
    log.Warn("unsupported currency requested, defaulting 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("error", err).Warn("conversion failed, using USD price")
    usd := p.GetPriceUsd(); price = &usd
}

Prevention

When it happens

Trigger: GET /product/{id} with a currency cookie/currency param that currencyservice cannot convert, or the Convert RPC returning an error/timeout.

Common situations: currencyservice down, unsupported currency code in the user's cookie (e.g. stale cookie after currency list change), request context canceled mid-conversion.

Related errors


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