技术博客
测吉凶错误处理与边界容错:ret_code 判断、空 expList、参数校验

测吉凶错误处理与边界容错:ret_code 判断、空 expList、参数校验

作者: 万维易源
2026-09-02
测吉凶错误处理空expList缓存
# 测吉凶错误处理与边界容错:ret_code 判断、空 expList、参数校验 > 接口/接入点:测吉凶 apiCode=1617(四个接入点) · 免费服务 · 适用人群:已接入的中高级开发者 · 阅读时间:约 7 分钟 ## 核心要点 - 成功判定要**双层**:外层 `showapi_res_code==0` 仅代表通道正常,业务必须再看 `showapi_res_body.ret_code=="0"`。 - 公司名接入点可能返回**空 expList**(`ret_code==0` 但无内容),须做空数组兜底,不能当失败也不能当异常。 - 免费档位有频限,正式上线建议加超时、基础参数校验与可选缓存,减少无效调用。 ## Why:上线前必须想清楚的边界 开发联调时一切正常,一上线就出现「页面空白」「偶发报错」「额度秒空」——多半是边界没处理:把外层码当业务成功、公司名空结果当异常、没设超时与频控。本文把这些坑一次列清。 ## What:三类需要处理的情形 | 情形 | 判断依据 | 正确处理 | |------|------|------| | 通道失败 | `showapi_res_code != 0` 或网络异常 | 提示系统错误,可重试 | | 业务失败 | `showapi_res_body.ret_code != "0"` | 读 `remark` 给用户看原因 | | 业务成功但空结果 | `ret_code=="0"` 且 `expList` 为空/缺失 | 显示「暂无分析」,非报错 | ## How:健壮调用模板(Python) ```python import requests def fortune(api_point, param_name, value, appkey): url = f"https://route.showapi.com/1617-{api_point}" try: r = requests.post(url, params={"appKey": appkey}, data={param_name: value}, timeout=15) r.raise_for_status() except requests.RequestException as e: return {"ok": False, "level": "channel", "msg": f"网络/通道异常:{e}"} outer = r.json() if outer.get("showapi_res_code") != 0: return {"ok": False, "level": "channel", "msg": outer.get("showapi_res_error") or "通道错误"} body = outer.get("showapi_res_body", {}) if body.get("ret_code") != "0": return {"ok": False, "level": "biz", "msg": body.get("remark") or "业务失败"} exp = body.get("expList") or [] if not exp: return {"ok": True, "empty": True, "msg": body.get("remark") or "暂未返回分析"} return {"ok": True, "empty": False, "expList": exp} # 调用示例 print(fortune("1", "mobile", "13770000000", "YOUR_APPKEY")) ``` ### 前端超时与参数校验(Node/浏览器) ```javascript async function fortune(type, param, value, appkey) { if (!value || !value.trim()) throw new Error("参数不能为空"); const url = `https://route.showapi.com/1617-${type}?appKey=${appkey}`; const res = await fetch(url, { method: "POST", body: new URLSearchParams({ [param]: value }), signal: AbortSignal.timeout(15000) }); const json = await res.json(); const b = json.showapi_res_body || {}; if (b.ret_code !== "0") throw new Error(b.remark || "业务失败"); return b.expList || []; // 空数组即「暂无分析」 } ``` ### cURL(排查通道/业务错误) ```bash curl -s -X POST "https://route.showapi.com/1617-4?appKey=YOUR_APPKEY" \ -H "content-type: application/x-www-form-urlencoded" \ --data-urlencode "companyName=某科技有限公司" | python -m json.tool ``` ## 返回示例与解析 - 业务失败示例(如缺参数):`showapi_res_body.ret_code` 非 0,`remark` 给出原因 → 前端展示 `remark`。 - 公司名空结果示例:`ret_code:"0"`、`remark:"查询成功!"`、无 `expList` → 归为「成功但空」,展示友好空态。 ## 进阶 / 边界 - **超时对齐文档**:接口 `x-read-timeout` 为 15s,示例统一设 `timeout=15` / `AbortSignal.timeout(15000)`。 - **缓存省额度**:`expList` 为「号码→结果」的确定性映射,可按 `type+input` 做缓存(如 Redis,TTL 数天),命中即返回,既提速又省免费档位。免费接口额度有限,缓存收益明显。 - **频控**:免费档位有调用限制,批量(如活动页多人同时测)建议加令牌桶限流,避免超限报错。 - **合规提示**:结果娱乐向,前端显著标注「仅供娱乐」,不要把「吉凶」当任何决策依据。 ## FAQ **Q:showapi_res_code 和 ret_code 都要判断吗?** 都要。`showapi_res_code` 是通道层(请求有没有正常被处理),`ret_code` 是业务层(有没有算出结果)。只看外层会漏掉业务失败。 **Q:公司名返回没 expList 算失败吗?** 不算。它是「ret_code=0 但空结果」,按成功分支展示「暂无分析」,不要报错也不要当异常重试。 **Q:免费接口要不要做缓存?** 建议做。`input→expList` 是确定性映射,缓存能省免费档位、提升响应。注意空结果也可缓存(避免重复空查)。 **Q:超时设多少合适?** 文档 read-timeout 为 15s,客户端超时设 15s 对齐即可;前端 AbortSignal.timeout(15000)。 ## 相关能力 / 下一步阅读 - [测吉凶返回字段全解:ret_code、remark 与 expList 数组一文读懂](https://www.showapi.com/guides/fortune-response-fields-1617) - [公司名测吉凶:接入点与「返回空 expList」边界说明](https://www.showapi.com/guides/fortune-company-guide-1617) - [expList 数组结构化解析:把「数理/签语/吉凶/详解」拆成字段](https://www.showapi.com/guides/fortune-expList-parse-1617) - **本系列共 13 篇**:查看[测吉凶指南总目录](https://www.showapi.com/guides/fortune-guides-1617)