{"record":{"id":"d3a33ceee734b97a","repo":"sundowndev/phoneinfoga","slug":"bad-request","errorCode":null,"errorMessage":"bad request","messagePattern":"bad request","errorType":"http","errorClass":"Error","httpStatus":400,"severity":"warning","filePath":"web/errors/errors.go","lineNumber":30,"sourceCode":"\nfunc (e *Error) Status() int {\n\treturn e.status\n}\n\nfunc (e *Error) Error() error {\n\treturn e.err\n}\n\nfunc (e *Error) String() string {\n\tif e.err == nil {\n\t\treturn \"unknown error\"\n\t}\n\treturn e.err.Error()\n}\n\nfunc NewBadRequest(err error) *Error {\n\tif err == nil {\n\t\terr = errors.New(\"bad request\")\n\t}\n\treturn &Error{\n\t\tstatus: http.StatusBadRequest,\n\t\terr:    err,\n\t}\n}\n\nfunc NewInternalError(err error) *Error {\n\tif err == nil {\n\t\terr = errors.New(\"internal error\")\n\t}\n\treturn &Error{\n\t\tstatus: http.StatusInternalServerError,\n\t\terr:    err,\n\t}\n}\n","sourceCodeStart":12,"sourceCodeEnd":47,"githubUrl":"https://github.com/sundowndev/phoneinfoga/blob/55807b05b753dab7bc6fe67403ca385668dda179/web/errors/errors.go#L12-L47","documentation":"NewBadRequest wraps an error into a web Error carrying HTTP 400; when called with nil, it substitutes the literal error 'bad request'. Handlers call it for user-input failures (missing/invalid parameters) detected in validate and the *Scan handlers.","triggerScenarios":"Calling NewBadRequest(nil) explicitly, or any web handler path where request validation fails — missing 'number' query parameter, invalid scan type in ValidateScanURL, malformed body — resulting in an HTTP 400 response.","commonSituations":"Client hitting the web API without the required ?number= parameter, sending an unsupported scanner type to ValidateScanURL, or a developer passing nil instead of a wrapped cause so the client only sees 'bad request'.","solutions":["Always pass the underlying error: NewBadRequest(fmt.Errorf(\"missing number parameter: %w\", err)) instead of nil","Fix the client request to include a valid phone number query parameter in international format","Check the HTTP response body/status: 400 means the request must be corrected, not retried as-is"],"exampleFix":"// before\nreturn weberrors.NewBadRequest(nil)   // client sees only \"bad request\"\n// after\nreturn weberrors.NewBadRequest(fmt.Errorf(\"query param 'number' is required\"))","handlingStrategy":"validation","validationCode":"// client-side check before calling the web API\nif !strings.HasPrefix(number, \"+\") || len(number) < 8 {\n    return errors.New(\"number parameter must be a full international phone number\")\n}\nreq, _ := http.NewRequest(\"GET\", apiURL+\"/scan?number=\"+url.QueryEscape(number), nil)","typeGuard":"func isBadRequest(err *weberrors.Error) bool {\n    return err != nil && err.Status() == http.StatusBadRequest\n}","tryCatchPattern":"resp, err := client.Do(req)\nif resp != nil && resp.StatusCode == http.StatusBadRequest {\n    var e struct{ Error string `json:\"error\"` }\n    _ = json.NewDecoder(resp.Body).Decode(&e)\n    return fmt.Errorf(\"fix request: %s\", e.Error) // do not retry 400\n}","preventionTips":["Always send ?number= in international format to the scan endpoints","Treat every 400 as a request bug — never retry unchanged","Server-side: pass a descriptive error to NewBadRequest instead of nil","Validate inputs client-side before hitting the API"],"tags":["http","web-api","bad-request","validation"],"backgroundTag":"http-400-bad-request","analyzedSha":"55807b05b753dab7bc6fe67403ca385668dda179","analyzedAt":"2026-09-03T13:37:27.908Z","contentChangedAt":"2026-09-03T13:37:27.908Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}