{"record":{"id":"fabe537b2dcd270e","repo":"iflytek/astron-agent","slug":"serviceresponseerror-fabe53","errorCode":"ServiceResponseError","errorMessage":"{message}","messagePattern":"\\{message\\}","errorType":"error_code","errorClass":"ServiceException","httpStatus":null,"severity":"error","filePath":"core/plugin/aitools/service/ocr_llm/req_ase_ability_ocr_service.py","lineNumber":388,"sourceCode":"        except Exception as e:\n            return {\n                \"file_index\": self.file_index,\n                \"page_index\": self.page_index,\n                \"name\": \"str\",\n                \"values\": f\"OCR 服务调用失败: {str(e)}\",\n                \"source_datas\": [],\n            }\n\n    def _handle_message(self, msg: Any) -> Tuple[str, str]:\n        data = msg\n        payload = data.get(\"payload\")\n        header = data.get(\"header\", {})\n\n        code = header.get(\"code\", 0)\n        message = header.get(\"message\", \"\")\n\n        if code != 0:\n            raise ServiceException.from_error_code(\n                CodeEnums.ServiceResponseError, extra_message=message\n            )\n\n        if not payload:\n            raise ServiceException.from_error_code(\n                CodeEnums.ServiceResponseError,\n                extra_message=\"OCR 服务返回载荷为空\",\n            )\n        else:\n            text = payload.get(\"result\", {}).get(\"text\", \"\")\n            if text:\n                tt = base64.b64decode(text).decode(encoding=\"utf-8\")\n                value = OcrRespParse.parse(json.loads(tt))\n                source_data = tt\n\n                return value, source_data\n            else:\n                raise ServiceException.from_error_code(","sourceCodeStart":370,"sourceCodeEnd":406,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/plugin/aitools/service/ocr_llm/req_ase_ability_ocr_service.py#L370-L406","documentation":"When streaming OCR results, the response header code is checked and any non-zero code is converted to a ServiceException with code ServiceResponseError, with the upstream engine's message appended. It signals the OCR provider rejected or failed the request.","triggerScenarios":"_invoke receives a message whose header.code != 0 (e.g. auth failure, invalid app_id/api_key, quota exceeded, engine internal error).","commonSituations":"Expired or wrong XFYUN API credentials; exhausted call quota; malformed request rejected by the OCR engine.","solutions":["Inspect the appended extra_message for the upstream error text/code","Verify app_id, api_key, api_secret and authorization signature for the OCR service","Check quota/billing on the OCR provider console","Catch ServiceException and match code ServiceResponseError to surface a friendly message"],"exampleFix":"// before\nresult, source = ocr_service.invoke(payload)  # unhandled\n// after\ntry:\n    result, source = ocr_service.invoke(payload)\nexcept ServiceException as e:\n    if e.code == CodeEnums.ServiceResponseError.code:\n        log.error('OCR upstream error: %s', e.message)","handlingStrategy":"try-catch","validationCode":"# credentials/config pre-check\nassert app_id and api_key and api_secret, 'OCR credentials must be configured'","typeGuard":null,"tryCatchPattern":"try:\n    value, source = ocr_service.invoke(req)\nexcept ServiceException as e:\n    if e.code == CodeEnums.ServiceResponseError.code:\n        log.error('OCR header error: %s', e.message)\n        raise UpstreamOcrError(e.message) from e","preventionTips":["Verify API credentials and signature generation regularly","Watch provider quota and billing alerts","Log the upstream header message verbatim for support tickets"],"tags":["ocr","upstream","service-exception"],"backgroundTag":"upstream-api-error","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}