{"record":{"id":"1f18e78b1bf98004","repo":"fish2018/pansou","slug":"s-json-w-1f18e7","errorCode":null,"errorMessage":"[%s] 解析JSON响应失败: %w","messagePattern":"\\[(.+?)\\] 解析JSON响应失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/ouge/ouge.go","lineNumber":154,"sourceCode":"\treq.Header.Set(\"Referer\", \"https://woog.nxog.eu.org/\")\n\treq.Header.Set(\"Cache-Control\", \"no-cache\")\n\t\n\t// 发送请求\n\tresp, err := p.doRequestWithRetry(req, client)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 搜索请求失败: %w\", p.Name(), err)\n\t}\n\tdefer resp.Body.Close()\n\t\n\t// 解析JSON响应\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 读取响应失败: %w\", p.Name(), err)\n\t}\n\t\n\tvar apiResponse OugeAPIResponse\n\tif err := json.Unmarshal(body, &apiResponse); err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 解析JSON响应失败: %w\", p.Name(), err)\n\t}\n\t\n\t// 检查API响应状态\n\tif apiResponse.Code != 1 {\n\t\treturn nil, fmt.Errorf(\"[%s] API返回错误: %s\", p.Name(), apiResponse.Msg)\n\t}\n\t\n\t// 解析搜索结果\n\tvar results []model.SearchResult\n\tfor _, item := range apiResponse.List {\n\t\tif result := p.parseAPIItem(item); result.Title != \"\" {\n\t\t\tresults = append(results, result)\n\t\t}\n\t}\n\t\n\treturn results, nil\n}\n","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/ouge/ouge.go#L136-L172","documentation":"Thrown when json.Unmarshal fails to decode the response body into OugeAPIResponse. The request and body read succeeded, but the payload is not valid JSON or its shape does not fit the struct (e.g. an HTML error page from a captive portal or CDN challenge).","triggerScenarios":"searchImpl receives a 200 whose body is not the expected JSON object: an HTML block page, empty body, a JSON array where an object is expected, or a field type mismatch (e.g. code as string instead of number).","commonSituations":"Domain fronted/CDN serving anti-bot HTML with status 200; site migration changed the API response schema; proxy returning an error page; truncated JSON from an interrupted body read that io.ReadAll still 'succeeded' on.","solutions":["Log a snippet of the raw body (body[:200]) to see what was actually returned","Check whether an anti-bot/CDN challenge page is being served and consider updating the Referer/UA or base URL","Verify the API schema still matches OugeAPIResponse (code/list/msg field types)","Validate the body starts with '{' before unmarshalling to give a clearer error"],"exampleFix":"// before\nif err := json.Unmarshal(body, &apiResponse); err != nil {\n    return nil, fmt.Errorf(\"[%s] 解析JSON响应失败: %w\", p.Name(), err)\n}\n// after\nif !json.Valid(body) || len(body) == 0 || body[0] != '{' {\n    return nil, fmt.Errorf(\"[%s] 非JSON响应: %.200s\", p.Name(), body)\n}\nif err := json.Unmarshal(body, &apiResponse); err != nil {\n    return nil, fmt.Errorf(\"[%s] 解析JSON响应失败: %w (body=%.200s)\", p.Name(), err, body)\n}","handlingStrategy":"validation","validationCode":"func looksLikeOugeJSON(body []byte) bool {\n    trimmed := bytes.TrimSpace(body)\n    return len(trimmed) > 0 && trimmed[0] == '{' && json.Valid(trimmed)\n}","typeGuard":null,"tryCatchPattern":"if err := json.Unmarshal(body, &apiResponse); err != nil {\n    var syn *json.SyntaxError\n    if errors.As(err, &syn) {\n        log.Printf(\"bad JSON at offset %d, body head: %.200s\", syn.Offset, body)\n    }\n    return fallbackSearch(keyword)\n}","preventionTips":["Always log a body snippet on unmarshal failure","Check Content-Type is application/json before parsing","Detect HTML challenge pages (starts with '<') early and treat as block","Re-verify struct fields against the live API when it upgrades"],"tags":["json","unmarshal","plugin","http-response"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"beaa56133755a548ebc51b090b3816e2ae044aa6","analyzedAt":"2026-09-07T00:31:18.025Z","contentChangedAt":"2026-09-07T00:31:18.025Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}