flipped-aurora/gin-vue-admin · error

大模型服务返回业务错误: code=%d msg=%s body=%s

Error message

大模型服务返回业务错误: code=%d msg=%s body=%s

What it means

When the body parses into commonResp.Response but its Code field does not equal commonResp.SUCCESS, LLMAuto treats it as an application-level business error from the LLM service and surfaces code, msg, and a body preview. The HTTP layer succeeded but the upstream reported failure inside its envelope.

Source

Thrown at server/service/system/auto_code_llm.go:54

	body, err := io.ReadAll(res.Body)
	if err != nil {
		return nil, fmt.Errorf("读取大模型响应失败: %w", err)
	}

	bodyPreview := previewResponseBody(body)
	contentType := res.Header.Get("Content-Type")
	if res.StatusCode < 200 || res.StatusCode >= 300 {
		return nil, fmt.Errorf("上游大模型服务返回非 2xx: status=%d content-type=%s body=%s", res.StatusCode, contentType, bodyPreview)
	}

	var resStruct commonResp.Response
	if err = json.Unmarshal(body, &resStruct); err != nil {
		return nil, fmt.Errorf("解析大模型响应失败: status=%d content-type=%s body=%s err=%w", res.StatusCode, contentType, bodyPreview, err)
	}

	if resStruct.Code != commonResp.SUCCESS {
		return nil, fmt.Errorf("大模型服务返回业务错误: code=%d msg=%s body=%s", resStruct.Code, resStruct.Msg, bodyPreview)
	}

	return resStruct.Data, nil
}

func (s *AutoCodeService) LLMAutoStream(ctx context.Context, llm common.JSONMap) (*http.Response, error) {
	path, err := buildLLMAutoPath(llm)
	if err != nil {
		return nil, err
	}

	payload := cloneLLMAutoJSONMap(llm)
	responseMode := strings.ToLower(strings.TrimSpace(fmt.Sprintf("%v", payload["response_mode"])))
	if responseMode == "" {
		payload["response_mode"] = "streaming"
	}

	res, err := request.HttpRequestWithContextAndTimeout(

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Read msg/body in the error to get the upstream's business reason
  2. Fix credentials/quota on the LLM provider account as indicated by the code/msg
  3. If the model is disallowed, switch llm config to a model the account can access
  4. Map recurring upstream business codes to friendlier messages in your API layer

Example fix

// before: raw passthrough of upstream business error
return nil, fmt.Errorf("大模型服务返回业务错误: code=%d msg=%s", resStruct.Code, resStruct.Msg)
// after: map known codes for callers
switch resStruct.Code {
case codeQuotaExceeded:
    return nil, fmt.Errorf("LLM 额度不足,请充值后重试 (code=%d)", resStruct.Code)
default:
    return nil, fmt.Errorf("大模型服务返回业务错误: code=%d msg=%s", resStruct.Code, resStruct.Msg)
}
Defensive patterns

Strategy: fallback

Type guard

func isBusinessError(resp commonResp.Response) bool {
    return resp.Code != commonResp.SUCCESS
}

Try / catch

data, err := svc.LLMAuto(ctx, llmCfg)
if err != nil {
    var bizErr *UpstreamBizError
    if errors.As(err, &bizErr) {
        // switch to fallback model/provider or surface bizErr.Code/Msg to the user
    }
    return err
}

Prevention

When it happens

Trigger: Upstream returns 200 with {code: != SUCCESS, msg: ...} — e.g. invalid token in the envelope, model access denied, quota exceeded reported at the application layer, or prompt/params rejected by the LLM backend.

Common situations: Expired upstream access token still yielding HTTP 200, insufficient account balance/quota on the LLM platform, disallowed model for the account, prompt flagged by content moderation returning a business error code.

Related errors


AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31). Data as JSON: /api/errors/a6c50ff108de43e2. Report an issue: GitHub.