星座运势查询返回 -1 是什么意思?两层状态码分层排查
约 13 分钟 进阶星座运势查询错误处理ret_code状态码排查
# 星座运势查询返回 -1 是什么意思?两层状态码分层排查
接口 872(两接入点)· 免费服务 · POST / GET · 返回 JSON · 适用:已接入开发者、需要做错误处理的工程师 · 阅读时间:约 7 分钟 · 最后实测核对:2026-09-18
## 核心要点
- 星座运势接口(apiCode=872)的响应有两层状态码:系统级 `showapi_res_code` 在根上,业务级 `showapi_res_body.ret_code` 在业务对象内。
- `showapi_res_body.ret_code` 为 `-1` 表示参数本身不成立,取值有 `星座和月份不能同时为空`、`输入星座不正确`、`输入星座月份不正确` 三种。
- 必填参数缺失是系统级错误,实测缺 `gender2` 时返回 `showapi_res_code: -1` 与英文错误信息,业务体为空。
## 两层状态码的区别
只看 HTTP 200 就认为调用成功,会漏掉所有业务级失败。ShowAPI 的响应把平台层与业务层的结果分开存放:平台层管鉴权、路由、频率,业务层管参数组合是否有意义。
两层都过才算真正拿到数据。两层字段的位置和取值口径如下:
| 层级 | 字段位置 | 成功值 | 覆盖范围 |
|---|---|---|---|
| 系统级 | 根 `showapi_res_code` | `0` | 鉴权、路由、必填参数校验、频率 |
| 业务级 | `showapi_res_body.ret_code` | `0` | 参数组合是否成立 |
`ret_code` 在接口文档里标注为字符串 `0`,2026-09-18 实测返回的是数字 `0`。
## 实测错误对照表(2026-09-18)
| 接口 | 传参 | `showapi_res_code` | `showapi_res_error` | `showapi_res_body` |
|---|---|---|---|---|
| 872-1 | 不传 `star` 与 `date` | `0` | 空 | `ret_code: -1`,`remark: 星座和月份不能同时为空` |
| 872-1 | `star=""` | `0` | 空 | `ret_code: -1`,`remark: 星座和月份不能同时为空` |
| 872-1 | `star=xxx` | `0` | 空 | `ret_code: -1`,`remark: 输入星座不正确` |
| 872-1 | `date=abc` | `0` | 空 | `ret_code: -1`,`remark: 输入星座月份不正确` |
| 872-1 | `date=20260819` | `0` | 空 | `ret_code: -1`,`remark: 输入星座月份不正确` |
| 872-2 | 缺 `gender2` | `-1` | `must input gender2 field` | 空对象 |
| 872-2 | `star1=xxx` | `0` | 空 | `ret_code: -1`,`remark: 未查询到相关星座之间的匹配,请确认输入是否正确!` |
| 872-1 / 872-2 | AppKey 无效 | `-1004` | `appKey err` | 空对象,`showapi_fee_num` 为 `0` |
| 872-1 | 完全不传 `appKey` | `-1002` | `appKey err` | 空对象 |
规律很清楚:参数值不合法落在业务层(`showapi_res_code` 仍为 `0`),必填参数缺失和鉴权失败落在系统层。
## 分层处理
Python:
```python
import requests
class HoroscopeError(Exception):
"""统一包装两层状态码的异常。"""
def call_horoscope(star: str, appkey: str, timeout: int = 15) -> dict:
try:
r = requests.get("https://route.showapi.com/872-1",
params={"appKey": appkey, "star": star},
timeout=timeout)
r.raise_for_status()
except requests.RequestException as e:
raise HoroscopeError(f"网络层失败: {e}") from e
data = r.json()
# 第一层:系统级。鉴权、必填参数、频率都在这层
code = data.get("showapi_res_code")
if code != 0:
if code in (-1004, -1002):
raise HoroscopeError(f"AppKey 校验未通过: {data.get('showapi_res_error')}")
raise HoroscopeError(f"系统错误 {code}: {data.get('showapi_res_error')}")
body = data.get("showapi_res_body") or {}
# 第二层:业务级。参数组合是否成立
if str(body.get("ret_code")) != "0":
raise HoroscopeError(f"业务失败: {body.get('remark')}")
return body
try:
body = call_horoscope("shizi", "YOUR_APPKEY")
except HoroscopeError as e:
print("运势暂不可用:", e) # 落日志并走兜底文案,页面不要白屏
```
cURL 看两层:
```bash
# 参数不合法:系统级仍是 0,业务级为 -1
curl -s -G "https://route.showapi.com/872-1" \
--data-urlencode "appKey=YOUR_APPKEY" \
--data-urlencode "star=xxx" \
--max-time 15
# 缺必填参数:系统级直接为 -1
curl -s -G "https://route.showapi.com/872-2" \
--data-urlencode "appKey=YOUR_APPKEY" \
--data-urlencode "star1=tianxie" \
--data-urlencode "gender1=1" \
--data-urlencode "star2=shuiping" \
--max-time 5
```
Node.js(fetch):
```javascript
const url = new URL("https://route.showapi.com/872-1");
url.searchParams.set("appKey", "YOUR_APPKEY");
url.searchParams.set("star", "shizi");
const res = await fetch(url, { signal: AbortSignal.timeout(15000) });
const data = await res.json();
// 第一层
if (data.showapi_res_code !== 0) {
const isAuth = [-1004, -1002].includes(data.showapi_res_code);
throw new Error(`${isAuth ? "AppKey 校验未通过" : "系统错误"}: ${data.showapi_res_error}`);
}
// 第二层
const body = data.showapi_res_body || {};
if (String(body.ret_code) !== "0") {
throw new Error(`业务失败: ${body.remark}`);
}
console.log(body.day.summary_star);
```
## 实测返回样例(2026-09-18)
参数不合法时,系统级正常、业务级失败:
```json
{
"showapi_res_error": "",
"showapi_res_code": 0,
"showapi_res_body": {
"remark": "输入星座不正确",
"ret_code": -1
}
}
```
必填参数缺失时,系统级直接失败:
```json
{
"showapi_res_error": "must input gender2 field",
"showapi_res_code": -1,
"showapi_res_body": {}
}
```
## 排查顺序
1. 先看 `showapi_res_code`。它是负数就停在这层,看 `showapi_res_error` 的文本。鉴权类实测为 `-1004`(AppKey 无效)与 `-1002`(未传 AppKey),必填参数缺失实测为 `-1`。
2. 系统级为 `0` 再看 `showapi_res_body.ret_code`。为 `-1` 时读 `remark`,它会直接说明是哪个参数不成立。
3. 两层都过但字段为空,检查 `needX` 开关有没有打开。未开启的周期键不会出现在返回里。
重试策略上,网络抖动与 5xx 可以做有限次指数退避;鉴权失败与参数不合法重试不会有不同结果,直接落日志走兜底文案。
## FAQ
**Q1:HTTP 200 但没有数据是怎么回事?**
多半是系统级 `showapi_res_code` 非 `0`,业务体为空。先看这个字段,再看 `showapi_res_body.ret_code`。
**Q2:`ret_code` 是数字还是字符串?**
2026-09-18 实测返回数字 `0`,接口文档标注为 String。判断时用 `str(body.get("ret_code")) != "0"` 最稳。
**Q3:缺一个必填参数会返回什么?**
实测 872-2 缺 `gender2` 时返回 `showapi_res_code: -1`、`showapi_res_error: must input gender2 field`、`showapi_res_body: {}`。这类错误落在系统级,不是业务级。
**Q4:AppKey 错了返回什么?**
实测 `showapi_res_code: -1004`、`showapi_res_error: appKey err`、业务体为空,且 `showapi_fee_num` 为 `0`。完全不传 `appKey` 时是 `-1002`。
**Q5:频率超限会返回什么?**
落在系统级,`showapi_res_code` 为非 `0`。做好缓存可以从源头减少触发频率限制的机会,见缓存策略那篇。
**Q6:业务失败也计费吗?**
实测 `showapi_fee_num` 在成功调用时为 `1`,鉴权失败时为 `0`。计费口径以接口文档与官方说明为准。
## 下一步阅读
- [星座运势查询的缓存怎么设](https://www.showapi.com/guides/horoscope-cache-872)
- [星座运势查询的 date 参数:按生日识别星座](https://www.showapi.com/guides/horoscope-by-date-872)
- [星座运势查询:用 Python / cURL / Node.js 跑通第一次调用](https://www.showapi.com/guides/horoscope-quickstart-872)
- [星座运势查询返回字段全解:五个周期的字段对照](https://www.showapi.com/guides/horoscope-response-fields-872)
- **本系列共 13 篇**:查看[星座运势 API 指南总目录](https://www.showapi.com/guides/horoscope-guides-872)





