{"record":{"id":"8de0d00a4b6deb7e","repo":"ZhuLinsen/daily_stock_analysis","slug":"baostock-rs-error-msg","errorCode":null,"errorMessage":"Baostock 查询失败: {rs.error_msg}","messagePattern":"Baostock 查询失败: (.+?)","errorType":"exception","errorClass":"DataFetchError","httpStatus":null,"severity":"error","filePath":"data_provider/baostock_fetcher.py","lineNumber":236,"sourceCode":"        bs_code = self._convert_stock_code(stock_code)\n        \n        logger.debug(f\"调用 Baostock query_history_k_data_plus({bs_code}, {start_date}, {end_date})\")\n        \n        with self._baostock_session() as bs:\n            try:\n                # 查询日线数据\n                # adjustflag: 1-后复权，2-前复权，3-不复权\n                rs = bs.query_history_k_data_plus(\n                    code=bs_code,\n                    fields=\"date,open,high,low,close,volume,amount,pctChg\",\n                    start_date=start_date,\n                    end_date=end_date,\n                    frequency=\"d\",  # 日线\n                    adjustflag=\"2\"  # 前复权\n                )\n                \n                if rs.error_code != '0':\n                    raise DataFetchError(f\"Baostock 查询失败: {rs.error_msg}\")\n                \n                # 转换为 DataFrame\n                data_list = []\n                while rs.next():\n                    data_list.append(rs.get_row_data())\n                \n                if not data_list:\n                    raise DataFetchError(f\"Baostock 未查询到 {stock_code} 的数据\")\n                \n                df = pd.DataFrame(data_list, columns=rs.fields)\n                \n                return df\n                \n            except Exception as e:\n                if isinstance(e, DataFetchError):\n                    raise\n                raise DataFetchError(f\"Baostock 获取数据失败: {e}\") from e\n    ","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/data_provider/baostock_fetcher.py#L218-L254","documentation":"A DataFetchError raised after a successful baostock login when bs.query_history_k_data_plus(...) returns a result set with error_code != '0'. Baostock reports per-query failures through the result object (not exceptions), so the fetcher checks error_code explicitly and surfaces error_msg; common codes include network receive failures ('网络接收错误') and invalid parameters.","triggerScenarios":"Calling query_history_k_data_plus with a malformed bs_code (e.g. 'sh.60051' typo), a date range where start > end, baostock socket receive errors mid-stream, or the service rejecting 'pctChg' field availability for some codes. The login succeeded, so credentials are fine — this is query-level.","commonSituations":"Bad stock code conversion feeding an invalid sh./sz. prefix; baostock server dropping the connection mid-query under load; querying suspended/ST codes with missing fields; date strings in the wrong 'YYYY-MM-DD' format.","solutions":["Log rs.error_msg — baostock's message names the exact problem (network receive error vs invalid code).","For '网络接收错误' style messages, retry once after a short sleep; these are transient.","Validate the converted bs_code format ('sh.600519'/'sz.000001') and date order before querying.","Fall back to Akshare for A-shares if the error persists."],"exampleFix":"# before\nrs = bs.query_history_k_data_plus(code=bs_code, ...)\nassert rs.error_code == '0'  # crashes opaquely\n\n# after\nrs = bs.query_history_k_data_plus(code=bs_code, ...)\nif rs.error_code != '0':\n    logger.warning('baostock query error %s: %s', rs.error_code, rs.error_msg)\n    if '网络' in rs.error_msg:\n        time.sleep(5)  # then retry once\n    else:\n        raise DataFetchError(f'Baostock 查询失败: {rs.error_msg}')","handlingStrategy":"retry","validationCode":"import re\nassert re.fullmatch(r'(sh|sz)\\.\\d{6}', bs_code), f'bad baostock code: {bs_code}'\nassert start_date <= end_date and re.fullmatch(r'\\d{4}-\\d{2}-\\d{2}', start_date)","typeGuard":null,"tryCatchPattern":"try:\n    df = baostock_fetcher.fetch(code, start, end)\nexcept DataFetchError as e:\n    if '查询失败' in str(e) and '网络' in str(e):\n        time.sleep(5)\n        df = baostock_fetcher.fetch(code, start, end)  # transient receive error\n    else:\n        raise","preventionTips":["Validate 'sh.NNNNNN'/'sz.NNNNNN' code format and date ordering before querying.","Retry only network-class error_msg values; parameter errors are permanent.","Keep an Akshare fallback for A-shares when baostock queries keep failing."],"tags":["baostock","query-error","a-shares","network"],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}