{"record":{"id":"fd9e95feeefcd59c","repo":"ZhuLinsen/daily_stock_analysis","slug":"market-label-stock-code","errorCode":null,"errorMessage":"{market_label} {stock_code} 获取失败:\n暂无可用数据源","messagePattern":"(.+?) (.+?) 获取失败:\n暂无可用数据源","errorType":"exception","errorClass":"DataFetchError","httpStatus":null,"severity":"error","filePath":"data_provider/base.py","lineNumber":1304,"sourceCode":"        #   - 未配置长桥:     YFinance 为首选（美股）, 通用 fetcher 循环（港股）\n        #   - 美股指数:       始终 YFinance 为首选（Longbridge 不提供指数K线）\n        is_us_index = is_us_index_code(stock_code)\n        is_us = is_us_index or is_us_stock_code(stock_code)\n        is_hk = (not is_us) and _is_hk_market(stock_code)\n        is_jp = (not is_us) and (not is_hk) and _is_jp_market(stock_code)\n        is_kr = (not is_us) and (not is_hk) and _is_kr_market(stock_code)\n        is_tw = (not is_us) and (not is_hk) and _is_tw_market(stock_code)\n        market = \"us\" if is_us else \"hk\" if is_hk else \"jp\" if is_jp else \"kr\" if is_kr else \"tw\" if is_tw else \"cn\"\n        if market != \"cn\":\n            fetchers = self._filter_daily_fetchers_for_market(fetchers, market)\n        fetchers = self._filter_fetchers_by_capability(fetchers, capability=\"daily_data\")\n        total_fetchers = len(fetchers)\n\n        if total_fetchers == 0:\n            market_label = \"美股指数\" if is_us_index else \"美股\" if is_us else \"港股\" if is_hk else \"台股\" if is_tw else \"A股\"\n            error_summary = f\"{market_label} {stock_code} 获取失败:\\n暂无可用数据源\"\n            logger.error(f\"[数据源终止] {stock_code} 获取失败: {error_summary}\")\n            raise DataFetchError(error_summary)\n\n        # 美股（含美股指数）使用专用路由；港股走下方通用数据源循环\n        # Failover chain: Finnhub(P2) -> AlphaVantage(P3) -> Yfinance(P4) -> Longbridge(P5)\n        # When Longbridge preferred: Longbridge -> Finnhub -> AlphaVantage -> Yfinance\n        if is_us:\n            prefer_lb = self._longbridge_preferred(capability=\"daily_data\") and not is_us_index\n            if is_us_index:\n                # 指数始终 YFinance 首选（Longbridge 不提供指数K线）\n                source_order = [\"YfinanceFetcher\", \"FinnhubFetcher\"]\n            elif prefer_lb:\n                source_order = [\"LongbridgeFetcher\", \"FinnhubFetcher\", \"AlphaVantageFetcher\", \"YfinanceFetcher\"]\n            else:\n                source_order = [\"FinnhubFetcher\", \"AlphaVantageFetcher\", \"YfinanceFetcher\", \"LongbridgeFetcher\"]\n            market_label = \"美股指数\" if is_us_index else \"美股\"\n\n            for order_index, src_name in enumerate(source_order):\n                fallback_to = (\n                    source_order[order_index + 1]","sourceCodeStart":1286,"sourceCodeEnd":1322,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/data_provider/base.py#L1286-L1322","documentation":"Raised by DataFetcherManager before any network call: after market detection (us/hk/jp/kr/tw/cn) and capability filtering ('daily_data'), zero fetchers remain. This is a configuration/availability failure, not a network failure — the failover loop never starts.","triggerScenarios":"get_daily_data on a market whose fetchers were all removed by _filter_daily_fetchers_for_market or _filter_fetchers_by_capability, e.g. a JP/KR/TW market where no fetcher supports daily_data, or all configured sources are disabled/unavailable.","commonSituations":"Running with a minimal .env (no API keys) so fetchers self-disable; adding a new market (JP/KR/TW) without a capable fetcher; capability metadata on a custom fetcher missing 'daily_data'.","solutions":["Inspect manager.available_fetchers to see which sources are actually registered and alive.","Enable/configure at least one data source that covers the failing market and declares the daily_data capability (e.g. YfinanceFetcher for US/JP/KR/TW, AkShare for A-share/HK).","If you added a custom fetcher, make sure its capability list includes 'daily_data' and it passes the market filter for the requested code."],"exampleFix":"# before: run headless with no keys -> 美股 AAPL 获取失败: 暂无可用数据源\n# after: .env\nYFINANCE_ENABLED=true  # or provide FINNHUB_API_KEY=...","handlingStrategy":"validation","validationCode":"names = manager.available_fetchers\nif not names:\n    raise SystemExit('no data sources configured — check .env / API keys')","typeGuard":null,"tryCatchPattern":"try:\n    df = manager.get_daily_data(code, ...)\nexcept DataFetchError as e:\n    if '暂无可用数据源' in str(e):\n        # configuration problem, fail fast — retrying is pointless\n        raise","preventionTips":["At startup, assert available_fetchers is non-empty and covers every market in your watchlist.","Wire required API keys in .env / CI secrets and keep .env.example in sync.","When adding a market (JP/KR/TW), first verify at least one fetcher declares daily_data for it."],"tags":["data-provider","configuration","no-sources","market-routing"],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}