fish2018/pansou · warning

parse html failed

Error message

parse html failed: %w

What it means

parseItems failed to parse the API-provided HTML fragment with goquery. goquery (via go-htmltransform/html parsing) rarely errors, so this usually indicates nil input or a parser-level failure; more practically it signals the fragment could not be turned into a queryable document for extracting div.layui-card results.

Solutions

  1. Log the fragment before parsing to confirm it contains expected markup
  2. Guard against empty apiResp.Data before parsing and return an empty result instead
  3. Update selectors if the site changed its markup (div.layui-card, a[onclick*=open_sid])
  4. Verify the goquery/html parser dependency versions are healthy

Example fix

// before
doc, err := goquery.NewDocumentFromReader(strings.NewReader(`<div id="yunso-root">` + fragment + `</div>`))
if err != nil {
    return nil, fmt.Errorf("parse html failed: %w", err)
}
// after
if strings.TrimSpace(fragment) == "" {
    return []YunsoItem{}, nil
}
doc, err := goquery.NewDocumentFromReader(strings.NewReader(`<div id="yunso-root">` + fragment + `</div>`))
if err != nil {
    return nil, fmt.Errorf("parse html failed: %w", err)
}
Defensive patterns

Strategy: fallback

Validate before calling

if strings.TrimSpace(fragment) == "" {
    return []YunsoItem{}, nil
}
if !strings.Contains(fragment, "layui-card") {
    log.Warn("yunso fragment missing expected markup")
}

Type guard

func hasExpectedMarkup(fragment string) bool {
    return strings.Contains(fragment, "layui-card") && strings.Contains(fragment, "data-qid")
}

Try / catch

items, err := parseItems(fragment)
if err != nil {
    log.Warn("yunso parse failed, returning empty", "err", err)
    items = []YunsoItem{}
}

Prevention

When it happens

Trigger: goquery.NewDocumentFromReader errors when parsing `<div id="yunso-root">` + fragment + `</div>` — e.g. apiResp.Data is empty or the fragment is not HTML as expected.

Common situations: The yunso API changed its result format (no longer HTML fragments), Data is empty/null for queries with no hits, or malformed HTML causes the underlying parser to fail.

Related errors


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

Appendix: source

Thrown at plugin/yunso/yunso.go:199

		return nil, fmt.Errorf("read response failed: %w", err)
	}

	var apiResp YunsoAPIResponse
	if err := jsonutil.Unmarshal(body, &apiResp); err != nil {
		return nil, fmt.Errorf("decode response failed: %w", err)
	}

	if apiResp.Code != 0 {
		return nil, fmt.Errorf("api returned error: %s", apiResp.Msg)
	}

	return p.parseItems(apiResp.Data)
}

func (p *YunsoAsyncPlugin) parseItems(fragment string) ([]YunsoItem, error) {
	doc, err := goquery.NewDocumentFromReader(strings.NewReader(`<div id="yunso-root">` + fragment + `</div>`))
	if err != nil {
		return nil, fmt.Errorf("parse html failed: %w", err)
	}

	items := make([]YunsoItem, 0, 16)
	doc.Find("div.layui-card[data-qid]").Each(func(_ int, card *goquery.Selection) {
		anchor := card.Find(`a[onclick*="open_sid"]`).First()
		if anchor.Length() == 0 {
			return
		}

		title := cleanYunsoText(anchor.Text())
		if title == "" {
			return
		}

		encryptedURL, _ := anchor.Attr("url")
		decryptedURL := ""
		if encryptedURL != "" {
			if decoded, err := decryptYunsoURL(encryptedURL); err == nil {

View on GitHub (pinned to beaa561337)