{"record":{"id":"356e9441474868ae","repo":"OpenBB-finance/OpenBB","slug":"failed-to-get-futures-curve-e-class-name","errorCode":null,"errorMessage":"Failed to get futures curve -> {e.__class__.__name__ if hasattr(e, '__class__') else e}: {e.args}","messagePattern":"Failed to get futures curve -> (.+?): (.+?)","errorType":"exception","errorClass":"OpenBBError","httpStatus":null,"severity":"error","filePath":"openbb_platform/providers/deribit/openbb_deribit/models/futures_curve.py","lineNumber":142,"sourceCode":"\n            if query.hours_ago is not None:\n                num_hours = query.hours_ago\n\n                hours_ago = (\n                    [int(d) for d in num_hours.split(\",\")]\n                    if isinstance(num_hours, str)\n                    else [int(num_hours)] if isinstance(num_hours, int) else num_hours\n                )\n\n                for hours in hours_ago:\n                    hours_data = await get_futures_curve_by_hours_ago(\n                        query.symbol, hours\n                    )\n                    if hours_data:\n                        data.extend(hours_data)\n            return data\n        except Exception as e:  # pylint: disable=broad-except\n            raise OpenBBError(\n                f\"Failed to get futures curve -> {e.__class__.__name__ if hasattr(e, '__class__') else e}: {e.args}\"\n            ) from e\n\n    @staticmethod\n    def transform_data(\n        query: DeribitFuturesCurveQueryParams, data: list, **kwargs: Any\n    ) -> list[DeribitFuturesCurveData]:\n        \"\"\"Transform the data.\"\"\"\n        # pylint: disable=import-outside-toplevel\n        from datetime import datetime  # noqa\n        from pandas import to_datetime\n\n        if not data:\n            raise EmptyDataError(\"No data found\")\n\n        futures_curve: list[DeribitFuturesCurveData] = []\n\n        for d in data:","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/OpenBB-finance/OpenBB/blob/3e071fcc2cd9f891cac6040ae60296dba76dab46/openbb_platform/providers/deribit/openbb_deribit/models/futures_curve.py#L124-L160","documentation":"The async fetch_data entry point wraps its entire body in a try/except and re-raises any failure as OpenBBError with the original exception's class name and args appended. This is a catch-all wrapper: the real cause is in the message (network timeout, HTTP error from Deribit, a parsing error in get_futures_curve_by_hours_ago, etc.). The 'from e' preserves the original as __cause__ for introspection.","triggerScenarios":"Deribit API unreachable (DNS/proxy/firewall); Deribit returning an unexpected payload shape that breaks parsing; rate-limited or 5xx responses inside get_futures_curve_by_hours_ago; an invalid expiry parsing in instrument names.","commonSituations":"Corporate egress blocking api.deribit.com; transient Deribit outages; schema drift when Deribit changes instrument naming; running in regions where Deribit is blocked.","solutions":["Inspect e.__cause__ / the exception class in the message to identify the real failure","For network causes, retry with backoff; Deribit's public API is generally reliable but geo-restrictions apply","For parsing causes, update the openbb_deribit package to the latest version (pip install -U openbb-deribit)"],"exampleFix":"# before\ntry:\n    data = await DeribitFuturesCurveFetcher.fetch_data(q, {})  # opaque 'Failed to get futures curve -> ...'\nexcept OpenBBError:\n    raise\n\n# after\ntry:\n    data = await DeribitFuturesCurveFetcher.fetch_data(q, {})\nexcept OpenBBError as e:\n    cause = e.__cause__\n    if isinstance(cause, (ConnectionError, TimeoutError)):\n        await asyncio.sleep(2 ** attempt)\n        continue  # retry with backoff\n    raise","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"from openbb_core.app.model.abstract.error import OpenBBError\n\nfor attempt in range(3):\n    try:\n        result = await fetcher.fetch_data(query, {})\n        break\n    except OpenBBError as e:\n        cause = e.__cause__\n        if isinstance(cause, (TimeoutError, ConnectionError)) and attempt < 2:\n            await asyncio.sleep(2 ** attempt)\n            continue\n        raise","preventionTips":["Always inspect __cause__ — the wrapper message alone is not actionable","Verify api.deribit.com is reachable from your network/region before scheduling jobs","Keep openbb-deribit updated to track Deribit schema changes"],"tags":["deribit","wrapper-exception","network","retry"],"backgroundTag":null,"analyzedSha":"3e071fcc2cd9f891cac6040ae60296dba76dab46","analyzedAt":"2026-08-14T23:40:48.960Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}