{"record":{"id":"fcf6693d55ba6e41","repo":"unknwon/the-way-to-go_ZH_CN","slug":"expected-get","errorCode":null,"errorMessage":"expected GET","messagePattern":"expected GET","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"eBook/16.10.md","lineNumber":50,"sourceCode":"... err1 := api.Func1()\nif err1 != nil {\n    fmt.Println(\"err: \" + err.Error())\n    return\n}\nerr2 := api.Func2()\nif err2 != nil {\n...\n    return\n}    \n```\n\n首先，包括在一个初始化的 `if` 语句中对函数的调用。但即使代码中到处都是以 `if` 语句的形式通知错误（通过打印错误信息）。通过这种方式，很难分辨什么是正常的程序逻辑，什么是错误检测或错误通知。还需注意的是，大部分代码都是致力于错误的检测。通常解决此问题的好办法是尽可能以闭包的形式封装你的错误检测，例如下面的代码：\n\n```go\nfunc httpRequestHandler(w http.ResponseWriter, req *http.Request) {\n    err := func () error {\n        if req.Method != \"GET\" {\n            return errors.New(\"expected GET\")\n        }\n        if input := parseInput(req); input != \"command\" {\n            return errors.New(\"malformed command\")\n        }\n        // 可以在此进行其他的错误检测\n    } ()\n\n        if err != nil {\n            w.WriteHeader(400)\n            io.WriteString(w, err)\n            return\n        }\n        doSomething() ...\n```\n\n这种方法可以很容易分辨出错误检测、错误通知和正常的程序逻辑（更详细的方式参考[第 13.5 小节](13.5.md)）。\n\n**在开始阅读[第 17 章](17.0.md)前，先回答下列 2 个问题：**","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/unknwon/the-way-to-go_ZH_CN/blob/7a54d34d3657084b6a59e5618bd069b912d571aa/eBook/16.10.md#L32-L68","documentation":"Error from the closure-based validation in the eBook's httpRequestHandler example (16.10.2): the anonymous func checks req.Method != \"GET\" first and returns errors.New(\"expected GET\") for any other verb; the outer code turns it into a 400 via w.WriteHeader(400) and io.WriteString(w, err). The snippet demonstrates concentrating all request validation in one closure so the handler body stays clean.","triggerScenarios":"Any non-GET request reaching this handler: POST/PUT/DELETE from a form submission, a CORS preflight OPTIONS, or curl defaulting to POST when given -d. The method check runs before parseInput, so a wrong verb always fails here even with a valid body.","commonSituations":"Front-end switched to fetch with method POST while the backend still demands GET; health-checkers and proxies sending HEAD; browser CORS preflight OPTIONS hitting the route; copy-pasting the book handler without aligning the allowed method with the client.","solutions":["Fix the client to use GET if the operation is a read: fetch(url) defaults to GET — remove method: 'POST'; drop curl -d","If other verbs are legitimate, return 405 Method Not Allowed with an Allow header instead of a bare 400 — 405 is the correct status for a wrong verb","Route by verb so the handler is never reached with the wrong method: Go 1.22+ net/http mux patterns like mux.HandleFunc(\"GET /path\", h)","Compare against the http.MethodGet constant instead of the literal \"GET\" to avoid typo class bugs"],"exampleFix":"// before (inside the closure)\nif req.Method != \"GET\" {\n\treturn errors.New(\"expected GET\")\n}\n// ...\nif err != nil {\n\tw.WriteHeader(400)\n\tio.WriteString(w, err)\n\treturn\n}\n\n// after\nif req.Method != http.MethodGet {\n\tw.Header().Set(\"Allow\", http.MethodGet)\n\tw.WriteHeader(http.StatusMethodNotAllowed)\n\tio.WriteString(w, \"expected GET\")\n\treturn nil\n}","handlingStrategy":"validation","validationCode":"// register the handler so only GET reaches it (Go 1.22+ method patterns)\nmux.HandleFunc(\"GET /command\", httpRequestHandler)","typeGuard":null,"tryCatchPattern":"err := func() error {\n\tif req.Method != http.MethodGet {\n\t\treturn errors.New(\"expected GET\")\n\t}\n\t// further checks...\n\treturn nil\n}()\nif err != nil {\n\thttp.Error(w, err.Error(), http.StatusBadRequest)\n\treturn\n}","preventionTips":["Compare with the http.MethodGet constant, never a bare \"GET\" string","Return 405 + Allow header for wrong verbs; reserve 400 for malformed payloads","Re-verify the client verb (fetch/axios/curl) after every API change; handle OPTIONS preflight explicitly or via CORS middleware","Use method-aware routing so wrong-verb requests never enter handler logic"],"tags":["go","http","method-validation","error-handling"],"backgroundTag":null,"analyzedSha":"7a54d34d3657084b6a59e5618bd069b912d571aa","analyzedAt":"2026-08-15T15:13:06.026Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}