fish2018/pansou · warning

内嵌结果字符串未闭合

Error message

内嵌结果字符串未闭合

What it means

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.

Solutions

  1. Log the tail of the body to confirm whether the page is truncated (ends mid-string)
  2. Retry the request — truncation is often transient CDN behavior
  3. Tighten the marker (include more surrounding context) so it can't match incidental occurrences
  4. Handle the error as 'malformed upstream page' and return empty results instead of failing the whole search if partial data is acceptable
Defensive patterns

Strategy: retry

Try / catch

if strings.Contains(err.Error(), "内嵌结果字符串未闭合") {
    // malformed/truncated page: retry once, then fall back to other sources
}

Prevention

When it happens

Trigger: 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.

Common situations: CDN/edge serving truncated cached pages; site emits the marker inside an escaped or commented context; response compressed-then-mangled by a broken intermediary.

Understand the failure class

Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.

Related errors


AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07). Data as JSON: /api/errors/26cc29eeb5fd5026. Report an issue: GitHub.

Appendix: source

Thrown at plugin/haitunsou/haitunsou.go:185

func indexBytes(data, marker []byte) int {
	return bytes.Index(data, marker)
}

func scanSingleQuotedString(body []byte, start int) ([]byte, error) {
	escaped := false
	for index := start; index < len(body); index++ {
		if escaped {
			escaped = false
			continue
		}
		switch body[index] {
		case '\\':
			escaped = true
		case '\'':
			return body[start:index], nil
		}
	}
	return nil, fmt.Errorf("内嵌结果字符串未闭合")
}

func decodeJSSingleQuotedString(encoded []byte) ([]byte, error) {
	decoded := make([]byte, 0, len(encoded))
	for index := 0; index < len(encoded); index++ {
		if encoded[index] != '\\' {
			decoded = append(decoded, encoded[index])
			continue
		}
		index++
		if index >= len(encoded) {
			return nil, fmt.Errorf("字符串以转义符结尾")
		}
		switch encoded[index] {
		case '\\', '\'', '"', '/':
			decoded = append(decoded, encoded[index])
		case 'b':
			decoded = append(decoded, '\b')

View on GitHub (pinned to beaa561337)