summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPratyush Shukla <ps4534@nyu.edu>2024-02-27 14:14:31 +0530
committerGitHub <noreply@github.com>2024-02-27 08:44:31 +0000
commit49967fee4768a6ba3ba0308d8ba88c6f03589865 (patch)
tree4c97d1a27ff5744219be1fc52ae38d3b9b9a8986
parent8e07b567524c325cdfebb3d872ff43870b64be21 (diff)
[Feature] Pretty Pydantic `ValidationError` exceptions (#6130)
* fix validator in fmp IndexHistorical model * make ValidationError pretty * modify arg error * linting fmp IndexHistorical * black * remove unused code
-rw-r--r--openbb_platform/core/openbb_core/app/static/utils/decorators.py32
-rw-r--r--openbb_platform/providers/fmp/openbb_fmp/models/index_historical.py7
2 files changed, 32 insertions, 7 deletions
diff --git a/openbb_platform/core/openbb_core/app/static/utils/decorators.py b/openbb_platform/core/openbb_core/app/static/utils/decorators.py
index 3c20559d475..7a9af5ead87 100644
--- a/openbb_platform/core/openbb_core/app/static/utils/decorators.py
+++ b/openbb_platform/core/openbb_core/app/static/utils/decorators.py
@@ -5,7 +5,7 @@ from typing import Any, Callable, Optional, TypeVar, overload
from openbb_core.app.model.abstract.error import OpenBBError
from openbb_core.env import Env
-from pydantic import validate_call
+from pydantic import ValidationError, validate_call
from typing_extensions import ParamSpec
P = ParamSpec("P")
@@ -44,14 +44,36 @@ def exception_handler(func: Callable[P, R]) -> Callable[P, R]:
"""Handle exceptions, attempting to focus on the last call from the traceback."""
@wraps(func)
- def wrapper(*args, **kwargs):
+ def wrapper(*f_args, **f_kwargs):
try:
- return func(*args, **kwargs)
- except Exception as e:
+ return func(*f_args, **f_kwargs)
+ except (ValidationError, Exception) as e:
if Env().DEBUG_MODE:
raise
+ if isinstance(e, ValidationError):
+ error_list = []
+
+ validation_error = f"{e.error_count()} validations errors in {e.title}"
+ for error in e.errors():
+ arg_error = f"Arg {error['loc'][0]} ->\n"
+ error_details = (
+ f" {error['msg']} "
+ f"[validation_error_type={error['type']}, "
+ f"input_type={type(error['input']).__name__}, "
+ f"input_value={error['input']}]\n"
+ )
+ error_info = f" For further information visit {error['url']}\n"
+ error_list.append(arg_error + error_details + error_info)
+
+ error_list.insert(0, validation_error)
+ error_str = "\n".join(error_list)
+ raise OpenBBError(
+ f"\nType -> ValidationError \n\nDetails -> {error_str}"
+ ) from None
+
+ # If the error is not a ValidationError, then it is a generic exception
raise OpenBBError(
- f"\nType -> {e.__class__.__name__}\n\nDetail -> {str(e)}"
+ f"\nType -> {e.original.original.__class__.__name__}\n\nDetail -> {str(e)}"
) from None
return wrapper
diff --git a/openbb_platform/providers/fmp/openbb_fmp/models/index_historical.py b/openbb_platform/providers/fmp/openbb_fmp/models/index_historical.py
index 8ebf3db2f38..087f6fa15f7 100644
--- a/openbb_platform/providers/fmp/openbb_fmp/models/index_historical.py
+++ b/openbb_platform/providers/fmp/openbb_fmp/models/index_historical.py
@@ -30,7 +30,7 @@ class FMPIndexHistoricalQueryParams(IndexHistoricalQueryParams):
Field(default="1day", description="Data granularity.")
)
- @field_validator("interval")
+ @field_validator("interval", mode="before", check_fields=True)
@classmethod
def map_interval(cls, v):
"""Map the interval from standard to the FMP format."""
@@ -104,9 +104,12 @@ class FMPIndexHistoricalFetcher(
return await get_data_many(url, "historical", **kwargs)
+ # pylint: disable=unused-argument
@staticmethod
def transform_data(
- query: FMPIndexHistoricalQueryParams, data: List[Dict], **kwargs: Any
+ query: FMPIndexHistoricalQueryParams,
+ data: List[Dict],
+ **kwargs: Any,
) -> List[FMPIndexHistoricalData]:
"""Return the transformed data."""
return [