// http_error.go 负责把非 2xx HTTP 响应整理成带响应体摘要的错误。 package modeladapter import ( "fmt" "io" "net/http" "strings" ) const ( // maxErrorBodyBytes 表示错误响应体最多读取的字节数。 maxErrorBodyBytes = 8192 ) // buildHTTPStatusError 读取响应体摘要并生成带状态码的错误。 func buildHTTPStatusError(prefix string, resp *http.Response) error { if resp == nil { return fmt.Errorf("%s response is nil", strings.TrimSpace(prefix)) } limitedBody, err := io.ReadAll(io.LimitReader(resp.Body, maxErrorBodyBytes)) if err != nil { if retrySummary := ProviderRetryAttemptSummary(resp); retrySummary != "" { return fmt.Errorf("%s status=%d %s body_read_error=%v", strings.TrimSpace(prefix), resp.StatusCode, retrySummary, err) } return fmt.Errorf("%s status=%d body_read_error=%v", strings.TrimSpace(prefix), resp.StatusCode, err) } retrySummary := ProviderRetryAttemptSummary(resp) bodyText := strings.TrimSpace(string(limitedBody)) if bodyText == "" { if retrySummary != "" { return fmt.Errorf("%s status=%d %s", strings.TrimSpace(prefix), resp.StatusCode, retrySummary) } return fmt.Errorf("%s status=%d", strings.TrimSpace(prefix), resp.StatusCode) } if retrySummary != "" { return fmt.Errorf("%s status=%d %s body=%s", strings.TrimSpace(prefix), resp.StatusCode, retrySummary, bodyText) } return fmt.Errorf("%s status=%d body=%s", strings.TrimSpace(prefix), resp.StatusCode, bodyText) }