{"record":{"id":"26cc29eeb5fd5026","repo":"fish2018/pansou","slug":"error-26cc29","errorCode":null,"errorMessage":"内嵌结果字符串未闭合","messagePattern":"内嵌结果字符串未闭合","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"plugin/haitunsou/haitunsou.go","lineNumber":185,"sourceCode":"func 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\n\t\tcase '\\'':\n\t\t\treturn body[start:index], nil\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"内嵌结果字符串未闭合\")\n}\n\nfunc decodeJSSingleQuotedString(encoded []byte) ([]byte, error) {\n\tdecoded := make([]byte, 0, len(encoded))\n\tfor index := 0; index < len(encoded); index++ {\n\t\tif encoded[index] != '\\\\' {\n\t\t\tdecoded = append(decoded, encoded[index])\n\t\t\tcontinue\n\t\t}\n\t\tindex++\n\t\tif index >= len(encoded) {\n\t\t\treturn nil, fmt.Errorf(\"字符串以转义符结尾\")\n\t\t}\n\t\tswitch encoded[index] {\n\t\tcase '\\\\', '\\'', '\"', '/':\n\t\t\tdecoded = append(decoded, encoded[index])\n\t\tcase 'b':\n\t\t\tdecoded = append(decoded, '\\b')","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/haitunsou/haitunsou.go#L167-L203","documentation":"Error returned by scanSingleQuotedString when, starting after the list marker, the scan reaches the end of the body without encountering a closing single quote. The marker was found but the quoted string literal that should follow it is unterminated — meaning the page is truncated or the marker matched incidental text (comment, analytics code) rather than the real results blob.","triggerScenarios":"The HTML body is cut off mid-string (connection closed early before this point — though body read already succeeded, the page itself is truncated/cached partial), or the marker string appears in a different context where no quoted literal follows, or a lone unescaped quote earlier in the string made the scan close early leaving the real content unterminated.","commonSituations":"CDN/edge serving truncated cached pages; site emits the marker inside an escaped or commented context; response compressed-then-mangled by a broken intermediary.","solutions":["Log the tail of the body to confirm whether the page is truncated (ends mid-string)","Retry the request — truncation is often transient CDN behavior","Tighten the marker (include more surrounding context) so it can't match incidental occurrences","Handle the error as 'malformed upstream page' and return empty results instead of failing the whole search if partial data is acceptable"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if strings.Contains(err.Error(), \"内嵌结果字符串未闭合\") {\n    // malformed/truncated page: retry once, then fall back to other sources\n}","preventionTips":["Retry truncated pages once before giving up","Check body tail for mid-string cutoff to distinguish truncation from marker mismatch","Broaden marker context so it can't match incidental occurrences","Add fuzz/round-trip tests for scanSingleQuotedString with escaped quotes"],"tags":["scraping","parsing","truncated-response"],"backgroundTag":"invalid-json-response","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"}