{"record":{"id":"c30b337a680179fc","repo":"GoogleCloudPlatform/microservices-demo","slug":"s","errorCode":null,"errorMessage":"%s","messagePattern":"%s","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/frontend/validator/validator.go","lineNumber":82,"sourceCode":"func (po *PlaceOrderPayload) Validate() error {\n\treturn validate.Struct(po)\n}\n\nfunc (sc *SetCurrencyPayload) Validate() error {\n\treturn validate.Struct(sc)\n}\n\n// Reusable error response function.\nfunc ValidationErrorResponse(err error) error {\n\tvalidationErrs, ok := err.(validator.ValidationErrors)\n\tif !ok {\n\t\treturn errors.New(\"invalid validation error format\")\n\t}\n\tvar msg string\n\tfor _, err := range validationErrs {\n\t\tmsg += fmt.Sprintf(\"Field '%s' is invalid: %s\\n\", err.Field(), err.Tag())\n\t}\n\treturn fmt.Errorf(\"%s\", msg)\n}\n","sourceCodeStart":64,"sourceCodeEnd":84,"githubUrl":"https://github.com/GoogleCloudPlatform/microservices-demo/blob/72ba613a05f7fcee51cf1d0badff401b6ae7074d/src/frontend/validator/validator.go#L64-L84","documentation":"ValidationErrorResponse in src/frontend/validator/validator.go converts go-playground/validator.ValidationErrors into a human-readable message, building one \"Field '<field>' is invalid: <tag>\" line per violation and returning fmt.Errorf(\"%s\", msg). If the error cannot be asserted to validator.ValidationErrors it returns errors.New(\"invalid validation error format\"). The returned message aggregates every failed field validation from form parsing (add-to-cart, place order, set currency).","triggerScenarios":"addToCartHandler, placeOrderHandler, or setCurrencyHandler parse a form/struct whose fields fail go-playground/validator tag rules (e.g. missing/invalid quantity, currency code, product id); ValidationErrorResponse then formats the ValidationErrors.","commonSituations":"User submits the form with empty or malformed fields; a bot or curl request posts without required form values; template/form field name changes desync the struct tags; currency code not matching expected enum/oneof tag.","solutions":["Read the returned message — each line names the field and the failed tag; fix the client to send valid values","Ensure the HTML form includes all fields required by the validator struct tags","Add client-side (HTML5 required/pattern) validation to catch bad input before submit","Check that struct tags match the current form field names after refactors","Handle the error as a 4xx (bad request) rendered to the user, not a server fault"],"exampleFix":"// before\nreturn fmt.Errorf(\"%s\", msg)\n// after\nmsg = strings.TrimSuffix(msg, \"\\n\")\nreturn fmt.Errorf(\"invalid input: %s\", msg)","handlingStrategy":"validation","validationCode":"qty := r.FormValue(\"quantity\")\nn, err := strconv.Atoi(qty)\nif err != nil || n < 1 || n > 100 {\n    http.Error(w, \"invalid quantity\", http.StatusBadRequest)\n    return\n}","typeGuard":"func isValidationError(err error) (validator.ValidationErrors, bool) {\n    var ve validator.ValidationErrors\n    if errors.As(err, &ve) {\n        return ve, true\n    }\n    return nil, false\n}","tryCatchPattern":"if err := validator.Struct(form); err != nil {\n    if ve, ok := isValidationError(err); ok {\n        http.Error(w, ValidationErrorResponse(ve).Error(), http.StatusBadRequest)\n        return\n    }\n    http.Error(w, \"invalid input\", http.StatusBadRequest)\n}","preventionTips":["Add HTML5 required/pattern attributes on form inputs","Keep validator struct tags in sync with form field names","Return 400 (not 500) for validation failures","Echo the per-field error lines back into the form UI"],"tags":["validation","golang","frontend","forms","validator"],"backgroundTag":"schema-validation-failed","analyzedSha":"72ba613a05f7fcee51cf1d0badff401b6ae7074d","analyzedAt":"2026-09-02T01:15:09.673Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}