GoogleCloudPlatform/microservices-demo · error
could not retrieve currencies
Error message
could not retrieve currencies
What it means
homeHandler fetches supported currencies via fe.getCurrencies (gRPC to the currency service). On any error it wraps with errors.Wrap(err, "could not retrieve currencies") and renders HTTP 500. This indicates the frontend could not obtain the currency list, so the home page cannot render prices.
Source
Thrown at src/frontend/handlers.go:64
frontendMessage = strings.TrimSpace(os.Getenv("FRONTEND_MESSAGE"))
isCymbalBrand = "true" == strings.ToLower(os.Getenv("CYMBAL_BRANDING"))
assistantEnabled = "true" == strings.ToLower(os.Getenv("ENABLE_ASSISTANT"))
templates = template.Must(template.New("").
Funcs(template.FuncMap{
"renderMoney": renderMoney,
"renderCurrencyLogo": renderCurrencyLogo,
}).ParseGlob("templates/*.html"))
plat platformDetails
)
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))View on GitHub (pinned to 72ba613a05)
Solutions
- Check currency service health/deployment (kubectl get pods, logs)
- Verify CURRENCY_SERVICE_ADDR resolves to the currency service host:port
- Inspect the wrapped cause (%+v / errors.Unwrap) for the gRPC status code
- Increase context timeout if DeadlineExceeded under load
- Add a fallback default currency list so the home page renders when currency service is down
Example fix
// before
currencies, err := fe.getCurrencies(r.Context())
if err != nil {
renderHTTPError(log, r, w, errors.Wrap(err, "could not retrieve currencies"), http.StatusInternalServerError)
return
}
// after
currencies, err := fe.getCurrencies(r.Context())
if err != nil {
log.WithError(err).Warn("could not retrieve currencies, using fallback")
currencies = defaultCurrencies
} Defensive patterns
Strategy: fallback
Validate before calling
if cs.currencySvcConn == nil {
return nil, errors.New("currency service connection not initialized")
} Try / catch
currencies, err := fe.getCurrencies(r.Context())
if err != nil {
log.WithError(err).Warn("currency list unavailable, using fallback")
currencies = defaultCurrencies
} Prevention
- Deploy readiness/liveness probes for the currency service
- Cache the supported-currencies list in the frontend
- Verify CURRENCY_SERVICE_ADDR during deploy checks
- Set sane RPC timeouts and retry on Unavailable
When it happens
Trigger: fe.getCurrencies(r.Context()) returns error: currency service unavailable, RPC deadline exceeded, or empty/error response from CurrencyService.GetSupportedCurrencies.
Common situations: Currency service pod down or crash-looping; CURRENCY_SERVICE_ADDR wrong; context deadline exceeded under load; network policy blocking frontend→currency traffic; service not deployed in the cluster.
Related errors
- could not retrieve products
- could not retrieve cart
- failed to do currency conversion for product %s
- failed to convert shipping cost to currency: %+v
- failed to convert price of %q to %s
AI-assisted analysis of GoogleCloudPlatform/microservices-demo@72ba613a05 (2026-09-02).
Data as JSON: /api/errors/1b0f597811ea2567.
Report an issue: GitHub.