{"record":{"id":"0697f8214edc1dc2","repo":"NanmiCoder/MediaCrawler","slug":"data-error-message","errorCode":null,"errorMessage":"{data.error.message}","messagePattern":"\\{data\\.error\\.message\\}","errorType":"exception","errorClass":"DataFetchError","httpStatus":null,"severity":"error","filePath":"media_platform/zhihu/client.py","lineNumber":121,"sourceCode":"        async with make_async_client(proxy=self.proxy) as client:\n            response = await client.request(method, url, timeout=self.timeout, **kwargs)\n\n        if response.status_code != 200:\n            utils.logger.error(f\"[ZhiHuClient.request] Requset Url: {url}, Request error: {response.text}\")\n            if response.status_code == 403:\n                raise ForbiddenError(response.text)\n            elif response.status_code == 404:  # Content without comments also returns 404\n                return {}\n\n            raise DataFetchError(response.text)\n\n        if return_response:\n            return response.text\n        try:\n            data: Dict = response.json()\n            if data.get(\"error\"):\n                utils.logger.error(f\"[ZhiHuClient.request] Request error: {data}\")\n                raise DataFetchError(data.get(\"error\", {}).get(\"message\"))\n            return data\n        except json.JSONDecodeError:\n            utils.logger.error(f\"[ZhiHuClient.request] Request error: {response.text}\")\n            raise DataFetchError(response.text)\n\n    async def get(self, uri: str, params=None, **kwargs) -> Union[Response, Dict, str]:\n        \"\"\"\n        GET request with header signing\n        Args:\n            uri: Request URI\n            params: Request parameters\n\n        Returns:\n\n        \"\"\"\n        final_uri = uri\n        if isinstance(params, dict):\n            final_uri += '?' + urlencode(params)","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/NanmiCoder/MediaCrawler/blob/d6f7c5bb906b6dac40ddf343ef9e26438a3de092/media_platform/zhihu/client.py#L103-L139","documentation":"DataFetchError raised inside ZhiHuClient.request when the response parsed as JSON successfully but contains a top-level 'error' object. Zhihu reports API-level failures (invalid parameters, missing content, permission denied) this way with HTTP 200, so the client checks data['error'] after parsing and raises with the API's own error.message.","triggerScenarios":"Requesting an answer/comment/content id that zhihu's API rejects (e.g. deleted content, wrong id format) or calling an endpoint without sufficient permission - HTTP is 200 but the body is an error envelope.","commonSituations":"Content ids harvested earlier that were later deleted; API contract changes adding new error cases; requesting logged-in-only content with an anonymous cookie.","solutions":["Read the error.message embedded in the exception - it is zhihu's own description of the rejected request.","Validate/sanitize content ids before requesting them.","If the message hints at login requirements, refresh the cookie.","Catch DataFetchError per item and skip the failing content."],"exampleFix":"// before\ncomments = await zhihu_client.get(uri, params=params)\n// after\ntry:\n    comments = await zhihu_client.get(uri, params=params)\nexcept DataFetchError as e:\n    utils.logger.info(f\"zhihu rejected {uri}: {e}\")\n    comments = {}","handlingStrategy":"try-catch","validationCode":"def looks_like_zhihu_id(content_id: str) -> bool:\n    return bool(content_id) and len(content_id) >= 6","typeGuard":null,"tryCatchPattern":"from media_platform.zhihu.exception import DataFetchError\ntry:\n    data = await zhihu_client.request(\"GET\", url)\nexcept DataFetchError as e:\n    if str(e).lower().startswith((\"err\", \"missing\", \"invalid\")):\n        utils.logger.info(f\"zhihu rejected content: {e}\")\n        return {}\n    raise","preventionTips":["Read the API's error.message embedded in the exception before guessing a cause.","Filter content IDs that previously errored instead of re-requesting them each run.","Watch for zhihu API error-envelope shape changes after site updates."],"tags":["zhihu","api-error","data-fetch"],"backgroundTag":null,"analyzedSha":"d6f7c5bb906b6dac40ddf343ef9e26438a3de092","analyzedAt":"2026-08-15T01:39:07.505Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}