fish2018/pansou · error

[ ] 创建会话请求失败

Error message

[%s] 创建会话请求失败: %w

What it means

postSessionRaw failed while constructing the outbound POST http.NewRequestWithContext to baseURL+path; this wraps the standard-library error. Because the URL is built from constant baseURL plus a fixed path with no user input, this almost always means an invalid URL composition or unsupported body/reader, which is rare and indicates a code/config bug rather than a runtime condition.

Solutions

  1. Print baseURL+path and run url.Parse on it to find the malformed component
  2. Verify baseURL is a full absolute URL like https://nsthwj.cn and path starts with /
  3. Check the wrapped error with %w — http.NewRequestWithContext errors name the exact parse failure
  4. If baseURL is configurable, validate it at plugin construction time
  5. Re-review recent changes to body/reader construction for a nil or closed reader

Example fix

// before
req, err := http.NewRequestWithContext(ctx, http.MethodPost, baseURL+path, reader)
if err != nil {
    return nil, fmt.Errorf("[%s] 创建会话请求失败: %w", p.Name(), err)
}
// after
fullURL := baseURL + path
if _, perr := url.Parse(fullURL); perr != nil {
    return nil, fmt.Errorf("[%s] 创建会话请求失败: 无效URL %q: %w", p.Name(), fullURL, perr)
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, fullURL, reader)
if err != nil {
    return nil, fmt.Errorf("[%s] 创建会话请求失败: %w", p.Name(), err)
}
Defensive patterns

Strategy: validation

Validate before calling

func validateBaseURL(u string) error {
    parsed, err := url.Parse(u)
    if err != nil || parsed.Scheme == "" || parsed.Host == "" {
        return fmt.Errorf("invalid baseURL: %q", u)
    }
    return nil
}

Try / catch

raw, err := plugin.SessionRawStatus()
if err != nil && strings.Contains(err.Error(), "创建会话请求失败") {
    // config/code bug: fail fast and surface to operator
    log.Error("session request construction failed — check baseURL", "err", err)
    return err
}

Prevention

When it happens

Trigger: baseURL or path contains characters making an unparseable URL (url.Parse error), an invalid HTTP method, or a nil context/broken reader passed to NewRequestWithContext.

Common situations: baseURL misconfigured (e.g. contains spaces or is empty after a config change), site migration left a malformed path constant, or a refactor changed the body handling so reader is invalid.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at plugin/nsgame/nsgame.go:357

	}
	var response nsgameSessionResponse
	if err := json.Unmarshal(data, &response); err != nil {
		return false, fmt.Errorf("[%s] 解析会话响应失败: %w", p.Name(), err)
	}
	active, _ := response.Data.(bool)
	return active, nil
}

func (p *NSGameAsyncPlugin) postSessionRaw(client *http.Client, path string, body []byte) ([]byte, error) {
	ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
	defer cancel()
	var reader io.Reader
	if body != nil {
		reader = strings.NewReader(string(body))
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, baseURL+path, reader)
	if err != nil {
		return nil, fmt.Errorf("[%s] 创建会话请求失败: %w", p.Name(), err)
	}
	if body != nil {
		req.Header.Set("Content-Type", "application/json")
	}
	p.setRequestHeaders(req, "https://nsthwj.cn/")
	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("[%s] 会话请求失败: %w", p.Name(), err)
	}
	defer resp.Body.Close()
	data, _ := io.ReadAll(resp.Body)
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("[%s] 会话返回状态码: %d", p.Name(), resp.StatusCode)
	}
	return data, nil
}

func solveChallenge(challenge string, difficultyBits int) string {

View on GitHub (pinned to beaa561337)