fish2018/pansou · error

[ ] 序列化请求体失败

Error message

[%s] 序列化请求体失败: %w

What it means

meitizy's searchImpl marshals the searchRequest struct (Title/Page/Size) to JSON with json.Marshal before sending the POST. This error wraps that marshal failure. All fields of searchRequest are plain JSON-serializable types, so this is essentially unreachable in normal operation and indicates an unexpected struct change (e.g. a field of an unserializable type like chan or func added).

Solutions

  1. Inspect the wrapped %w error and recent changes to the searchRequest struct
  2. Remove or fix the unserializable field, or add a json:"-" tag to exclude it
  3. Add a unit test marshaling searchRequest to catch regressions

Example fix

// before
Type: someChan // json.Marshal fails on chan
// after
//  exclude non-serializable fields from the wire format
someChan any `json:"-"`
Defensive patterns

Strategy: type-guard

Validate before calling

if _, err := json.Marshal(searchRequest{Title: keyword, Page: 1, Size: MaxPageSize}); err != nil {
    log.Printf("searchRequest not serializable: %v", err)
}

Try / catch

if err != nil {
    log.Printf("marshal failed: %v", err)
    return nil, err // programmer error: fail fast, do not retry
}

Prevention

When it happens

Trigger: json.Marshal fails on the searchRequest struct — only possible if the struct gains a field with a type json cannot encode (channel, func, cyclic pointer) or a MarshalJSON method that returns an error.

Common situations: A developer extends searchRequest with an unsupported field type or a custom MarshalJSON that errors; keyword content never affects this because strings always serialize.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


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

Appendix: source

Thrown at plugin/meitizy/meitizy.go:146

// SearchWithResult 执行搜索并返回包含IsFinal标记的结果
func (p *MeitizyPlugin) SearchWithResult(keyword string, ext map[string]interface{}) (model.PluginSearchResult, error) {
	return p.AsyncSearchWithResult(keyword, p.searchImpl, p.MainCacheKey, ext)
}

// searchImpl 搜索实现
func (p *MeitizyPlugin) searchImpl(client *http.Client, keyword string, ext map[string]interface{}) ([]model.SearchResult, error) {
	// 构建请求体
	reqBody := searchRequest{
		Title: keyword,
		Page:  1,
		Size:  MaxPageSize,
	}

	// 序列化请求体
	jsonData, err := json.Marshal(reqBody)
	if err != nil {
		return nil, fmt.Errorf("[%s] 序列化请求体失败: %w", p.Name(), err)
	}

	// 构建请求URL
	apiURL := BaseURL + SearchPath

	// 创建带超时的上下文
	ctx, cancel := context.WithTimeout(context.Background(), RequestTimeout)
	defer cancel()

	// 创建POST请求
	req, err := http.NewRequestWithContext(ctx, "POST", apiURL, bytes.NewBuffer(jsonData))
	if err != nil {
		return nil, fmt.Errorf("[%s] 创建请求失败: %w", p.Name(), err)
	}

	// 设置请求头
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("User-Agent", UserAgent)

View on GitHub (pinned to beaa561337)