frontend: use pkg/errors, show full stacktrace
Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
This commit is contained in:
parent
f8ddac9c52
commit
ca3ace3f65
6 changed files with 56 additions and 66 deletions
|
@ -20,6 +20,10 @@ spec:
|
||||||
value: "7070"
|
value: "7070"
|
||||||
- name: LISTEN_ADDR
|
- name: LISTEN_ADDR
|
||||||
value: "0.0.0.0"
|
value: "0.0.0.0"
|
||||||
|
- name: GRPC_TRACE
|
||||||
|
value: "all"
|
||||||
|
- name: GRPC_VERBOSITY
|
||||||
|
value: "debug"
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
cpu: 200m
|
cpu: 200m
|
||||||
|
|
|
@ -3,7 +3,7 @@ RUN apt update && apt install net-tools telnet
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN dotnet restore && \
|
RUN dotnet restore && \
|
||||||
dotnet build \
|
dotnet build && \
|
||||||
dotnet publish
|
dotnet publish
|
||||||
WORKDIR /app/bin/Debug/netcoreapp2.0
|
WORKDIR /app/bin/Debug/netcoreapp2.0
|
||||||
ENTRYPOINT ["dotnet", "cartservice.dll", "start"]
|
ENTRYPOINT ["dotnet", "cartservice.dll", "start"]
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
pb "frontend/genproto"
|
pb "frontend/genproto"
|
||||||
)
|
)
|
||||||
|
@ -36,7 +37,7 @@ func ensureSessionID(next http.HandlerFunc) http.HandlerFunc {
|
||||||
MaxAge: cookieMaxAge,
|
MaxAge: cookieMaxAge,
|
||||||
})
|
})
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
renderHTTPError(w, fmt.Errorf("unrecognized cookie error: %+v", err), http.StatusInternalServerError)
|
renderHTTPError(w, errors.Wrap(err, "unrecognized cookie error"), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
sessionID = c.Value
|
sessionID = c.Value
|
||||||
|
@ -51,17 +52,17 @@ func (fe *frontendServer) homeHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Printf("[home] session_id=%s currency=%s", sessionID(r), currentCurrency(r))
|
log.Printf("[home] session_id=%s currency=%s", sessionID(r), currentCurrency(r))
|
||||||
currencies, err := fe.getCurrencies(r.Context())
|
currencies, err := fe.getCurrencies(r.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
renderHTTPError(w, fmt.Errorf("could not retrieve currencies: %+v", err), http.StatusInternalServerError)
|
renderHTTPError(w, errors.Wrap(err, "could not retrieve currencies"), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
products, err := fe.getProducts(r.Context())
|
products, err := fe.getProducts(r.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
renderHTTPError(w, fmt.Errorf("could not retrieve products: %+v", err), http.StatusInternalServerError)
|
renderHTTPError(w, errors.Wrap(err, "could not retrieve products"), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cart, err := fe.getCart(r.Context(), sessionID(r))
|
cart, err := fe.getCart(r.Context(), sessionID(r))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
renderHTTPError(w, fmt.Errorf("could not retrieve cart: %+v", err), http.StatusInternalServerError)
|
renderHTTPError(w, errors.Wrap(err, "could not retrieve cart"), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +74,7 @@ func (fe *frontendServer) homeHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
for i, p := range products {
|
for i, p := range products {
|
||||||
price, err := fe.convertCurrency(r.Context(), p.GetPriceUsd(), currentCurrency(r))
|
price, err := fe.convertCurrency(r.Context(), p.GetPriceUsd(), currentCurrency(r))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
renderHTTPError(w, fmt.Errorf("failed to do currency conversion for product %s: %+v", p.GetId(), err), http.StatusInternalServerError)
|
renderHTTPError(w, errors.Wrapf(err, "failed to do currency conversion for product %s", p.GetId()), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ps[i] = productView{p, price}
|
ps[i] = productView{p, price}
|
||||||
|
@ -93,36 +94,36 @@ func (fe *frontendServer) homeHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
func (fe *frontendServer) productHandler(w http.ResponseWriter, r *http.Request) {
|
func (fe *frontendServer) productHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
id := mux.Vars(r)["id"]
|
id := mux.Vars(r)["id"]
|
||||||
if id == "" {
|
if id == "" {
|
||||||
renderHTTPError(w, fmt.Errorf("product id not specified"), http.StatusBadRequest)
|
renderHTTPError(w, errors.New("product id not specified"), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Printf("[productHandler] id=%s currency=%s session=%s", id, currentCurrency(r), sessionID(r))
|
log.Printf("[productHandler] id=%s currency=%s session=%s", id, currentCurrency(r), sessionID(r))
|
||||||
p, err := fe.getProduct(r.Context(), id)
|
p, err := fe.getProduct(r.Context(), id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
renderHTTPError(w, fmt.Errorf("could not retrieve product: %+v", err), http.StatusInternalServerError)
|
renderHTTPError(w, errors.Wrap(err, "could not retrieve product"), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
currencies, err := fe.getCurrencies(r.Context())
|
currencies, err := fe.getCurrencies(r.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
renderHTTPError(w, fmt.Errorf("could not retrieve currencies: %+v", err), http.StatusInternalServerError)
|
renderHTTPError(w, errors.Wrap(err, "could not retrieve currencies"), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cart, err := fe.getCart(r.Context(), sessionID(r))
|
cart, err := fe.getCart(r.Context(), sessionID(r))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
renderHTTPError(w, fmt.Errorf("could not retrieve cart: %+v", err), http.StatusInternalServerError)
|
renderHTTPError(w, errors.Wrap(err, "could not retrieve cart"), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
price, err := fe.convertCurrency(r.Context(), p.GetPriceUsd(), currentCurrency(r))
|
price, err := fe.convertCurrency(r.Context(), p.GetPriceUsd(), currentCurrency(r))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
renderHTTPError(w, fmt.Errorf("failed to convert currency: %+v", err), http.StatusInternalServerError)
|
renderHTTPError(w, errors.Wrap(err, "failed to convert currency"), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
recommendations, err := fe.getRecommendations(r.Context(), sessionID(r), []string{id})
|
recommendations, err := fe.getRecommendations(r.Context(), sessionID(r), []string{id})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
renderHTTPError(w, fmt.Errorf("failed to get product recommendations: %+v", err), http.StatusInternalServerError)
|
renderHTTPError(w, errors.Wrap(err, "failed to get product recommendations"), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,19 +148,19 @@ func (fe *frontendServer) addToCartHandler(w http.ResponseWriter, r *http.Reques
|
||||||
quantity, _ := strconv.ParseUint(r.FormValue("quantity"), 10, 32)
|
quantity, _ := strconv.ParseUint(r.FormValue("quantity"), 10, 32)
|
||||||
productID := r.FormValue("product_id")
|
productID := r.FormValue("product_id")
|
||||||
if productID == "" || quantity == 0 {
|
if productID == "" || quantity == 0 {
|
||||||
renderHTTPError(w, fmt.Errorf("invalid form input"), http.StatusBadRequest)
|
renderHTTPError(w, errors.New("invalid form input"), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Printf("[addToCart] product_id=%s qty=%d session_id=%s", productID, quantity, sessionID(r))
|
log.Printf("[addToCart] product_id=%s qty=%d session_id=%s", productID, quantity, sessionID(r))
|
||||||
|
|
||||||
p, err := fe.getProduct(r.Context(), productID)
|
p, err := fe.getProduct(r.Context(), productID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
renderHTTPError(w, fmt.Errorf("could not retrieve product: %+v", err), http.StatusInternalServerError)
|
renderHTTPError(w, errors.Wrap(err, "could not retrieve product"), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := fe.insertCart(r.Context(), sessionID(r), p.GetId(), int32(quantity)); err != nil {
|
if err := fe.insertCart(r.Context(), sessionID(r), p.GetId(), int32(quantity)); err != nil {
|
||||||
renderHTTPError(w, fmt.Errorf("failed to add to cart: %+v", err), http.StatusInternalServerError)
|
renderHTTPError(w, errors.Wrap(err, "failed to add to cart"), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.Header().Set("location", "/cart")
|
w.Header().Set("location", "/cart")
|
||||||
|
@ -170,7 +171,7 @@ func (fe *frontendServer) emptyCartHandler(w http.ResponseWriter, r *http.Reques
|
||||||
log.Printf("[emptyCart] session_id=%s", sessionID(r))
|
log.Printf("[emptyCart] session_id=%s", sessionID(r))
|
||||||
|
|
||||||
if err := fe.emptyCart(r.Context(), sessionID(r)); err != nil {
|
if err := fe.emptyCart(r.Context(), sessionID(r)); err != nil {
|
||||||
renderHTTPError(w, fmt.Errorf("failed to empty cart: %+v", err), http.StatusInternalServerError)
|
renderHTTPError(w, errors.Wrap(err, "failed to empty cart"), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.Header().Set("location", "/")
|
w.Header().Set("location", "/")
|
||||||
|
@ -181,24 +182,24 @@ func (fe *frontendServer) viewCartHandler(w http.ResponseWriter, r *http.Request
|
||||||
log.Printf("[viewCart] session_id=%s", sessionID(r))
|
log.Printf("[viewCart] session_id=%s", sessionID(r))
|
||||||
currencies, err := fe.getCurrencies(r.Context())
|
currencies, err := fe.getCurrencies(r.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
renderHTTPError(w, fmt.Errorf("could not retrieve currencies: %+v", err), http.StatusInternalServerError)
|
renderHTTPError(w, errors.Wrap(err, "could not retrieve currencies"), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cart, err := fe.getCart(r.Context(), sessionID(r))
|
cart, err := fe.getCart(r.Context(), sessionID(r))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
renderHTTPError(w, fmt.Errorf("could not retrieve cart: %+v", err), http.StatusInternalServerError)
|
renderHTTPError(w, errors.Wrap(err, "could not retrieve cart"), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
recommendations, err := fe.getRecommendations(r.Context(), sessionID(r), cartIDs(cart))
|
recommendations, err := fe.getRecommendations(r.Context(), sessionID(r), cartIDs(cart))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
renderHTTPError(w, fmt.Errorf("failed to get product recommendations: %+v", err), http.StatusInternalServerError)
|
renderHTTPError(w, errors.Wrap(err, "failed to get product recommendations"), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
shippingCost, err := fe.getShippingQuote(r.Context(), cart, currentCurrency(r))
|
shippingCost, err := fe.getShippingQuote(r.Context(), cart, currentCurrency(r))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
renderHTTPError(w, fmt.Errorf("failed to get shipping quote: %+v", err), http.StatusInternalServerError)
|
renderHTTPError(w, errors.Wrap(err, "failed to get shipping quote"), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,12 +213,12 @@ func (fe *frontendServer) viewCartHandler(w http.ResponseWriter, r *http.Request
|
||||||
for i, item := range cart {
|
for i, item := range cart {
|
||||||
p, err := fe.getProduct(r.Context(), item.GetProductId())
|
p, err := fe.getProduct(r.Context(), item.GetProductId())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
renderHTTPError(w, fmt.Errorf("could not retrieve product #%s: %+v", item.GetProductId(), err), http.StatusInternalServerError)
|
renderHTTPError(w, errors.Wrapf(err, "could not retrieve product #%s", item.GetProductId()), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
price, err := fe.convertCurrency(r.Context(), p.GetPriceUsd(), currentCurrency(r))
|
price, err := fe.convertCurrency(r.Context(), p.GetPriceUsd(), currentCurrency(r))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
renderHTTPError(w, fmt.Errorf("could not convert currency for product #%s: %+v", item.GetProductId(), err), http.StatusInternalServerError)
|
renderHTTPError(w, errors.Wrapf(err, "could not convert currency for product #%s", item.GetProductId()), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +281,7 @@ func (fe *frontendServer) placeOrderHandler(w http.ResponseWriter, r *http.Reque
|
||||||
Country: country},
|
Country: country},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
renderHTTPError(w, fmt.Errorf("failed to complete the order: %+v", err), http.StatusInternalServerError)
|
renderHTTPError(w, errors.Wrap(err, "failed to complete the order"), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Printf("order #%s completed", order.GetOrder().GetOrderId())
|
log.Printf("order #%s completed", order.GetOrder().GetOrderId())
|
||||||
|
@ -334,10 +335,12 @@ func (fe *frontendServer) setCurrencyHandler(w http.ResponseWriter, r *http.Requ
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderHTTPError(w http.ResponseWriter, err error, code int) {
|
func renderHTTPError(w http.ResponseWriter, err error, code int) {
|
||||||
log.Printf("[error] %+v (code=%d)", err, code)
|
log.Printf("[error](code=%d) %+v ", code, err)
|
||||||
|
errMsg := fmt.Sprintf("%+v", err)
|
||||||
|
|
||||||
w.WriteHeader(code)
|
w.WriteHeader(code)
|
||||||
templates.ExecuteTemplate(w, "error", map[string]interface{}{
|
templates.ExecuteTemplate(w, "error", map[string]interface{}{
|
||||||
"error": err.Error(),
|
"error": errMsg,
|
||||||
"status_code": code,
|
"status_code": code,
|
||||||
"status": http.StatusText(code)})
|
"status": http.StatusText(code)})
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,9 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
|
@ -56,6 +59,7 @@ func main() {
|
||||||
if os.Getenv("PORT") != "" {
|
if os.Getenv("PORT") != "" {
|
||||||
srvPort = os.Getenv("PORT")
|
srvPort = os.Getenv("PORT")
|
||||||
}
|
}
|
||||||
|
addr := os.Getenv("LISTEN_ADDR")
|
||||||
svc := new(frontendServer)
|
svc := new(frontendServer)
|
||||||
mustMapEnv(&svc.productCatalogSvcAddr, "PRODUCT_CATALOG_SERVICE_ADDR")
|
mustMapEnv(&svc.productCatalogSvcAddr, "PRODUCT_CATALOG_SERVICE_ADDR")
|
||||||
mustMapEnv(&svc.currencySvcAddr, "CURRENCY_SERVICE_ADDR")
|
mustMapEnv(&svc.currencySvcAddr, "CURRENCY_SERVICE_ADDR")
|
||||||
|
@ -64,31 +68,12 @@ func main() {
|
||||||
mustMapEnv(&svc.checkoutSvcAddr, "CHECKOUT_SERVICE_ADDR")
|
mustMapEnv(&svc.checkoutSvcAddr, "CHECKOUT_SERVICE_ADDR")
|
||||||
mustMapEnv(&svc.shippingSvcAddr, "SHIPPING_SERVICE_ADDR")
|
mustMapEnv(&svc.shippingSvcAddr, "SHIPPING_SERVICE_ADDR")
|
||||||
|
|
||||||
var err error
|
mustConnGRPC(ctx, &svc.currencySvcConn, svc.currencySvcAddr)
|
||||||
svc.currencySvcConn, err = grpc.DialContext(ctx, svc.currencySvcAddr, grpc.WithInsecure())
|
mustConnGRPC(ctx, &svc.productCatalogSvcConn, svc.productCatalogSvcAddr)
|
||||||
if err != nil {
|
mustConnGRPC(ctx, &svc.cartSvcConn, svc.cartSvcAddr)
|
||||||
log.Fatalf("failed to connect currency service: %+v", err)
|
mustConnGRPC(ctx, &svc.recommendationSvcConn, svc.recommendationSvcAddr)
|
||||||
}
|
mustConnGRPC(ctx, &svc.shippingSvcConn, svc.shippingSvcAddr)
|
||||||
svc.productCatalogSvcConn, err = grpc.DialContext(ctx, svc.productCatalogSvcAddr, grpc.WithInsecure())
|
mustConnGRPC(ctx, &svc.checkoutSvcConn, svc.checkoutSvcAddr)
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("failed to connect productcatalog service: %+v", err)
|
|
||||||
}
|
|
||||||
svc.cartSvcConn, err = grpc.DialContext(ctx, svc.cartSvcAddr, grpc.WithInsecure())
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("failed to connect cart service at %s: %+v", svc.cartSvcAddr, err)
|
|
||||||
}
|
|
||||||
svc.recommendationSvcConn, err = grpc.DialContext(ctx, svc.recommendationSvcAddr, grpc.WithInsecure())
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("failed to connect recommendation service at %s: %+v", svc.recommendationSvcAddr, err)
|
|
||||||
}
|
|
||||||
svc.shippingSvcConn, err = grpc.DialContext(ctx, svc.shippingSvcAddr, grpc.WithInsecure())
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("failed to connect shipping service at %s: %+v", svc.shippingSvcAddr, err)
|
|
||||||
}
|
|
||||||
svc.checkoutSvcConn, err = grpc.DialContext(ctx, svc.checkoutSvcAddr, grpc.WithInsecure())
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("failed to connect checkout service at %s: %+v", svc.checkoutSvcAddr, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
r := mux.NewRouter()
|
r := mux.NewRouter()
|
||||||
r.HandleFunc("/", ensureSessionID(svc.homeHandler)).Methods(http.MethodGet, http.MethodHead)
|
r.HandleFunc("/", ensureSessionID(svc.homeHandler)).Methods(http.MethodGet, http.MethodHead)
|
||||||
|
@ -100,8 +85,8 @@ func main() {
|
||||||
r.HandleFunc("/logout", svc.logoutHandler).Methods(http.MethodGet)
|
r.HandleFunc("/logout", svc.logoutHandler).Methods(http.MethodGet)
|
||||||
r.HandleFunc("/cart/checkout", ensureSessionID(svc.placeOrderHandler)).Methods(http.MethodPost)
|
r.HandleFunc("/cart/checkout", ensureSessionID(svc.placeOrderHandler)).Methods(http.MethodPost)
|
||||||
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("./static/"))))
|
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("./static/"))))
|
||||||
log.Printf("starting server on :" + srvPort)
|
log.Printf("starting server on " + addr + ":" + srvPort)
|
||||||
log.Fatal(http.ListenAndServe(":"+srvPort, r))
|
log.Fatal(http.ListenAndServe(addr+":"+srvPort, r))
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustMapEnv(target *string, envKey string) {
|
func mustMapEnv(target *string, envKey string) {
|
||||||
|
@ -111,3 +96,11 @@ func mustMapEnv(target *string, envKey string) {
|
||||||
}
|
}
|
||||||
*target = v
|
*target = v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mustConnGRPC(ctx context.Context, conn **grpc.ClientConn, addr string) {
|
||||||
|
var err error
|
||||||
|
*conn, err = grpc.DialContext(ctx, addr, grpc.WithInsecure(), grpc.WithTimeout(time.Second*3))
|
||||||
|
if err != nil {
|
||||||
|
panic(errors.Wrapf(err, "grpc: failed to connect %s", addr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,13 +2,10 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"google.golang.org/grpc/codes"
|
|
||||||
|
|
||||||
pb "frontend/genproto"
|
pb "frontend/genproto"
|
||||||
|
|
||||||
"google.golang.org/grpc/status"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -44,10 +41,6 @@ func (fe *frontendServer) getProduct(ctx context.Context, id string) (*pb.Produc
|
||||||
|
|
||||||
func (fe *frontendServer) getCart(ctx context.Context, userID string) ([]*pb.CartItem, error) {
|
func (fe *frontendServer) getCart(ctx context.Context, userID string) ([]*pb.CartItem, error) {
|
||||||
resp, err := pb.NewCartServiceClient(fe.cartSvcConn).GetCart(ctx, &pb.GetCartRequest{UserId: userID})
|
resp, err := pb.NewCartServiceClient(fe.cartSvcConn).GetCart(ctx, &pb.GetCartRequest{UserId: userID})
|
||||||
if status.Code(err) == codes.Canceled {
|
|
||||||
// TODO(ahmetb) remove this workaround when cartservice returns ok response to GetCart() with non-existing users
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return resp.GetItems(), err
|
return resp.GetItems(), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,10 +78,7 @@ func (fe *frontendServer) getShippingQuote(ctx context.Context, items []*pb.Cart
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
localized, err := fe.convertCurrency(ctx, quote.GetCostUsd(), currency)
|
localized, err := fe.convertCurrency(ctx, quote.GetCostUsd(), currency)
|
||||||
if err != nil {
|
return localized, errors.Wrap(err, "failed to convert currency for shipping cost")
|
||||||
return nil, fmt.Errorf("failed to convert currency for shipping cost: %+v", err)
|
|
||||||
}
|
|
||||||
return localized, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fe *frontendServer) getRecommendations(ctx context.Context, userID string, productIDs []string) ([]*pb.Product, error) {
|
func (fe *frontendServer) getRecommendations(ctx context.Context, userID string, productIDs []string) ([]*pb.Product, error) {
|
||||||
|
@ -101,7 +91,7 @@ func (fe *frontendServer) getRecommendations(ctx context.Context, userID string,
|
||||||
for i, v := range resp.GetProductIds() {
|
for i, v := range resp.GetProductIds() {
|
||||||
p, err := fe.getProduct(ctx, v)
|
p, err := fe.getProduct(ctx, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to get recommended product info (#%s): %+v", v, err)
|
return nil, errors.Wrapf(err, "failed to get recommended product info (#%s)", v)
|
||||||
}
|
}
|
||||||
out[i] = p
|
out[i] = p
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<p>Something has failed. Below are some details for debugging.</p>
|
<p>Something has failed. Below are some details for debugging.</p>
|
||||||
|
|
||||||
<p><strong>HTTP Status:</strong> {{.status_code}} {{.status}}</p>
|
<p><strong>HTTP Status:</strong> {{.status_code}} {{.status}}</p>
|
||||||
<pre class="border border-danger"
|
<pre class="border border-danger p-3"
|
||||||
style="white-space: pre-wrap; word-break: keep-all;">
|
style="white-space: pre-wrap; word-break: keep-all;">
|
||||||
{{- .error -}}
|
{{- .error -}}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
Loading…
Reference in a new issue