in src/frontend/handlers.go [144:209]
func (fe *frontendServer) productHandler(w http.ResponseWriter, r *http.Request) {
log := r.Context().Value(ctxKeyLog{}).(logrus.FieldLogger)
id := mux.Vars(r)["id"]
if id == "" {
renderHTTPError(log, r, w, errors.New("product id not specified"), http.StatusBadRequest)
return
}
log.WithField("id", id).WithField("currency", currentCurrency(r)).
Debug("serving product page")
p, err := fe.getProduct(r.Context(), id)
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() {
packagingInfo, err = httpGetPackagingInfo(id)
if err != nil {
fmt.Println("Failed to obtain product's packaging info:", err)
}
}
if err := templates.ExecuteTemplate(w, "product", injectCommonTemplateData(r, map[string]interface{}{
"ad": fe.chooseAd(r.Context(), p.Categories, log),
"show_currency": true,
"currencies": currencies,
"product": product,
"recommendations": recommendations,
"cart_size": cartSize(cart),
"packagingInfo": packagingInfo,
})); err != nil {
log.Println(err)
}
}