fish2018/pansou · warning

[ ] 编码搜索关键词失败

Error message

[%s] 编码搜索关键词失败: %w

What it means

fetchSearch wraps any failure from encodeGB18030 (converting the search keyword to GB18030 bytes, required because the target site uses that encoding) with this contextual error. It means the keyword could not be encoded for the site's GB18030 search form.

Solutions

  1. Sanitize the keyword before calling fetchSearch: strip or replace characters unsupported by GB18030
  2. Fall back to UTF-8 encoding or URL-encoded raw keyword if GB18030 encoding fails
  3. Update encodeGB18030 to use charmap/GB18030 encoder with replacement for unmapped runes
  4. Log the offending keyword to identify which characters break encoding

Example fix

// before
encoded, err := encodeGB18030(keyword)
if err != nil {
    return nil, fmt.Errorf("[%s] 编码搜索关键词失败: %w", p.Name(), err)
}
// after
encoded, err := encodeGB18030(keyword)
if err != nil {
    log.Warnf("[%s] GB18030 encode failed for %q, falling back to raw: %v", p.Name(), keyword, err)
    encoded = []byte(keyword)
}
Defensive patterns

Strategy: fallback

Validate before calling

// Go
for _, r := range keyword {
    if r > 0x10FFFF || isControl(r) { return errors.New("keyword contains unsupported characters") }
}

Try / catch

doc, err := p.fetchSearch(client, keyword)
if err != nil && strings.Contains(err.Error(), "编码搜索关键词失败") {
    // retry with sanitized keyword
}

Prevention

When it happens

Trigger: Calling searchImpl -> fetchSearch with a keyword that encodeGB18030 cannot convert (unsupported runes / encoder failure) — typically exotic characters outside GB18030's coverage.

Common situations: Users searching with rare emoji or rare CJK-ext characters; keywords containing control characters; combining search terms copied from other apps.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at plugin/5266ys/5266ys.go:169

				}
				if imageURL != "" {
					result.Images = []string{imageURL}
				}
				mu.Lock()
				results = append(results, result)
				mu.Unlock()
			}
		}()
	}
	wg.Wait()

	return plugin.FilterResultsByKeyword(results, keyword), nil
}

func (p *Plugin) fetchSearch(client *http.Client, keyword string) (*goquery.Document, error) {
	encoded, err := encodeGB18030(keyword)
	if err != nil {
		return nil, fmt.Errorf("[%s] 编码搜索关键词失败: %w", p.Name(), err)
	}
	form := "show=title%2Csmalltext&tempid=1&tbname=article&keyboard=" + url.QueryEscape(string(encoded)) + "&submit="
	ctx, cancel := context.WithTimeout(context.Background(), requestTimeout)
	defer cancel()
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, baseURL+searchPath, strings.NewReader(form))
	if err != nil {
		return nil, fmt.Errorf("[%s] 创建搜索请求失败: %w", p.Name(), err)
	}
	setHeaders(req, baseURL+"/")
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("[%s] 搜索请求失败: %w", p.Name(), err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("[%s] 搜索请求返回 HTTP %d", p.Name(), resp.StatusCode)
	}

View on GitHub (pinned to beaa561337)