{"record":{"id":"a468d2be4a6792c2","repo":"GoogleCloudPlatform/microservices-demo","slug":"failed-to-add-to-cart","errorCode":null,"errorMessage":"failed to add to cart","messagePattern":"failed to add to cart","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"src/frontend/handlers.go","lineNumber":232,"sourceCode":"\tproductID := r.FormValue(\"product_id\")\n\tpayload := validator.AddToCartPayload{\n\t\tQuantity:  quantity,\n\t\tProductID: productID,\n\t}\n\tif err := payload.Validate(); err != nil {\n\t\trenderHTTPError(log, r, w, validator.ValidationErrorResponse(err), http.StatusUnprocessableEntity)\n\t\treturn\n\t}\n\tlog.WithField(\"product\", payload.ProductID).WithField(\"quantity\", payload.Quantity).Debug(\"adding to cart\")\n\n\tp, err := fe.getProduct(r.Context(), payload.ProductID)\n\tif err != nil {\n\t\trenderHTTPError(log, r, w, errors.Wrap(err, \"could not retrieve product\"), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tif err := fe.insertCart(r.Context(), sessionID(r), p.GetId(), int32(payload.Quantity)); err != nil {\n\t\trenderHTTPError(log, r, w, errors.Wrap(err, \"failed to add to cart\"), http.StatusInternalServerError)\n\t\treturn\n\t}\n\tw.Header().Set(\"location\", baseUrl + \"/cart\")\n\tw.WriteHeader(http.StatusFound)\n}\n\nfunc (fe *frontendServer) emptyCartHandler(w http.ResponseWriter, r *http.Request) {\n\tlog := r.Context().Value(ctxKeyLog{}).(logrus.FieldLogger)\n\tlog.Debug(\"emptying cart\")\n\n\tif err := fe.emptyCart(r.Context(), sessionID(r)); err != nil {\n\t\trenderHTTPError(log, r, w, errors.Wrap(err, \"failed to empty cart\"), http.StatusInternalServerError)\n\t\treturn\n\t}\n\tw.Header().Set(\"location\", baseUrl + \"/\")\n\tw.WriteHeader(http.StatusFound)\n}\n","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/GoogleCloudPlatform/microservices-demo/blob/72ba613a05f7fcee51cf1d0badff401b6ae7074d/src/frontend/handlers.go#L214-L250","documentation":"addToCartHandler failed to insert the item into the cart via fe.insertCart (cartservice InsertItem RPC). The error is wrapped as \"failed to add to cart\" and rendered as HTTP 500; the redirect to /cart never happens.","triggerScenarios":"POST /cart when cartservice InsertItem returns an error: cart service down, deadline exceeded, or a quantity<=0 rejected by the cart service's validation.","commonSituations":"cartservice crash/restart mid-request, redis backend (cart store) unavailable, negative or zero quantity submitted from a tampered form.","solutions":["Check cartservice and its redis backend health.","Verify CART_SERVICE_ADDR configuration.","Validate quantity > 0 before calling insertCart.","Inspect the wrapped root cause in frontend logs via renderHTTPError output."],"exampleFix":"// before\nif err := fe.insertCart(r.Context(), sessionID(r), p.GetId(), int32(payload.Quantity)); err != nil {\n// after\nif payload.Quantity <= 0 {\n    renderHTTPError(log, r, w, errors.New(\"invalid quantity\"), http.StatusBadRequest)\n    return\n}\nif err := fe.insertCart(r.Context(), sessionID(r), p.GetId(), int32(payload.Quantity)); err != nil {","handlingStrategy":"validation","validationCode":"if payload.Quantity <= 0 {\n    http.Error(w, \"quantity must be positive\", http.StatusBadRequest)\n    return\n}\nif sessionID(r) == \"\" {\n    http.Error(w, \"missing session\", http.StatusBadRequest)\n    return\n}","typeGuard":"func validAddToCart(qty int32, productID, userID string) bool {\n    return qty > 0 && productID != \"\" && userID != \"\"\n}","tryCatchPattern":"if err := fe.insertCart(r.Context(), sessionID(r), p.GetId(), int32(payload.Quantity)); err != nil {\n    if status.Code(err) == codes.Unavailable {\n        log.Warn(\"cartservice unavailable; retry advised\")\n    }\n    renderHTTPError(log, r, w, errors.Wrap(err, \"failed to add to cart\"), http.StatusInternalServerError)\n    return\n}","preventionTips":["Validate quantity and session before the RPC.","Retry insertCart with backoff on codes.Unavailable.","Keep cartservice's redis backend monitored.","Log the wrapped root cause chain."],"tags":["grpc","http-500","cart","microservices"],"backgroundTag":"rpc-service-unavailable","analyzedSha":"72ba613a05f7fcee51cf1d0badff401b6ae7074d","analyzedAt":"2026-09-02T01:15:09.673Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}