GoogleCloudPlatform/microservices-demo · error
could not retrieve products
Error message
could not retrieve products
What it means
homeHandler fetches the product catalog via fe.getProducts (gRPC ProductCatalogService.ListProducts). On error it wraps with errors.Wrap(err, "could not retrieve products") and renders HTTP 500, since the home page cannot display products.
Source
Thrown at src/frontend/handlers.go:69
"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))
for i, p := range products {
price, err := fe.convertCurrency(r.Context(), p.GetPriceUsd(), currentCurrency(r))
if err != nil {
renderHTTPError(log, r, w, errors.Wrapf(err, "failed to do currency conversion for product %s", p.GetId()), http.StatusInternalServerError)
returnView on GitHub (pinned to 72ba613a05)
Solutions
- Check product catalog service pods and logs for startup/loading errors
- Verify PRODUCT_CATALOG_SERVICE_ADDR points to the correct service and port
- Inspect the wrapped underlying error for the gRPC status code
- Confirm the catalog data file is mounted/present in the catalog service
- Retry or raise timeouts if the catalog service is intermittently slow
Example fix
// before
products, err := fe.getProducts(r.Context())
if err != nil {
renderHTTPError(log, r, w, errors.Wrap(err, "could not retrieve products"), http.StatusInternalServerError)
return
}
// after
products, err := fe.getProducts(r.Context())
if err != nil {
log.WithError(err).Error("could not retrieve products")
renderHTTPError(log, r, w, errors.Wrap(err, "could not retrieve products"), http.StatusServiceUnavailable)
return
} Defensive patterns
Strategy: retry
Validate before calling
if fe.productCatalogConn == nil {
return nil, errors.New("product catalog connection not initialized")
} Try / catch
products, err := fe.getProducts(r.Context())
if err != nil {
if status.Code(err) == codes.Unavailable {
// retry once with backoff before failing the request
}
renderHTTPError(log, r, w, errors.Wrap(err, "could not retrieve products"), http.StatusServiceUnavailable)
return
} Prevention
- Ensure catalog service has persistent catalog data mounted
- Add gRPC retry policy for idempotent ListProducts calls
- Monitor catalog service latency/errors with tracing
- Verify PRODUCT_CATALOG_SERVICE_ADDR in every environment
When it happens
Trigger: fe.getProducts(r.Context()) returns error: product catalog service unavailable, RPC error/deadline, or ListProducts returning a failure status.
Common situations: Product catalog service crash-looping or not deployed; PRODUCT_CATALOG_SERVICE_ADDR misconfigured; catalog data failing to load in the service (empty products.csv mount); deadlines hit when the catalog service is overloaded.
Related errors
- could not retrieve currencies
- could not retrieve cart
- failed to do currency conversion for product %s
- product id not specified
- failed to prepare order: %+v
AI-assisted analysis of GoogleCloudPlatform/microservices-demo@72ba613a05 (2026-09-02).
Data as JSON: /api/errors/467a07501b2abc72.
Report an issue: GitHub.