{"record":{"id":"99536007aa16aa5c","repo":"fish2018/pansou","slug":"json-w-995360","errorCode":null,"errorMessage":"解析结果 JSON 失败: %w","messagePattern":"解析结果 JSON 失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/haitunsou/haitunsou.go","lineNumber":162,"sourceCode":"\t\t\tstart = index + len(marker)\n\t\t\tbreak\n\t\t}\n\t}\n\tif start < 0 {\n\t\treturn nil, fmt.Errorf(\"未找到页面内嵌结果\")\n\t}\n\n\tencoded, err := scanSingleQuotedString(body, start)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdecoded, err := decodeJSSingleQuotedString(encoded)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar items []searchItem\n\tif err := jsonutil.Unmarshal(decoded, &items); err != nil {\n\t\treturn nil, fmt.Errorf(\"解析结果 JSON 失败: %w\", err)\n\t}\n\treturn items, nil\n}\n\nfunc indexBytes(data, marker []byte) int {\n\treturn bytes.Index(data, marker)\n}\n\nfunc scanSingleQuotedString(body []byte, start int) ([]byte, error) {\n\tescaped := false\n\tfor index := start; index < len(body); index++ {\n\t\tif escaped {\n\t\t\tescaped = false\n\t\t\tcontinue\n\t\t}\n\t\tswitch body[index] {\n\t\tcase '\\\\':\n\t\t\tescaped = true","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/haitunsou/haitunsou.go#L144-L180","documentation":"Returned by parseEmbeddedList when jsonutil.Unmarshal fails to decode the extracted, escape-decoded string into []searchItem. The embedded string was found and scanned correctly, but its contents are not a JSON array matching the searchItem schema. Typically this means the site changed the data shape (array to object, added wrapper, renamed structure) or the JS-escape decoding produced corrupt bytes.","triggerScenarios":"The inline 'const list = JSON.parse('...' )' string unquotes to JSON that does not fit []searchItem: root is an object not an array, fields have different types (e.g. id became a string), or decodeJSSingleQuotedString mangled multi-byte content.","commonSituations":"Upstream schema evolution (is_type values change, url field renamed); decoder bug with unusual \\x or surrogate-pair escapes; page contains a marker-like string in a comment with non-JSON content following it.","solutions":["errors.Unwrap to see the json syntax/type error and byte offset, then fetch and inspect the decoded payload at that offset","Update the searchItem struct's json tags/types to match the new upstream schema","If the root became an object, adjust parseEmbeddedList to unwrap the results field before unmarshal","Verify decodeJSSingleQuotedString output is valid UTF-8 (utf8.Valid) before unmarshaling"],"exampleFix":"// before\ntype searchItem struct {\n    ID    int64  `json:\"id\"`\n    URL   string `json:\"url\"`\n}\n// after — tolerate upstream sending id as string\nvar items []struct {\n    ID    json.Number `json:\"id\"`\n    URL   string      `json:\"url\"`\n}","handlingStrategy":"try-catch","validationCode":"decoded, err := decodeJSSingleQuotedString(encoded)\nif err != nil { return err }\nif !utf8.Valid(decoded) {\n    return fmt.Errorf(\"decoded payload is not valid UTF-8\")\n}","typeGuard":"func looksLikeItemArray(b []byte) bool {\n    var probe []map[string]json.RawMessage\n    return json.Unmarshal(b, &probe) == nil\n}","tryCatchPattern":"var jsonErr *json.UnmarshalTypeError\nif errors.As(err, &jsonErr) {\n    // schema drift at field jsonErr.Field: update searchItem tags\n} else if errors.As(err, &syntaxErr) {\n    // decoding bug or truncated payload\n}","preventionTips":["Pin searchItem schema against recorded upstream payloads in unit tests","Validate decoded bytes are UTF-8 before unmarshal","Log the offending byte offset from the json error for diagnosis","Wrap searchItem field types loosely (json.Number) to survive upstream type drift"],"tags":["json","unmarshal","schema-mismatch"],"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"}