feat: implement structured exception classes with error codes and sug… (#3279)
This commit is contained in:
+181
-30
@@ -9,6 +9,7 @@ import requests
|
||||
|
||||
from mem0.client.project import AsyncProject, Project
|
||||
from mem0.client.utils import api_error_handler
|
||||
# Exception classes are referenced in docstrings only
|
||||
from mem0.memory.setup import get_user_id, setup_config
|
||||
from mem0.memory.telemetry import capture_client_event
|
||||
|
||||
@@ -139,7 +140,12 @@ class MemoryClient:
|
||||
A dictionary containing the API response.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
"""
|
||||
kwargs = self._prepare_params(kwargs)
|
||||
if kwargs.get("output_format") != "v1.1":
|
||||
@@ -173,7 +179,12 @@ class MemoryClient:
|
||||
A dictionary containing the memory data.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
"""
|
||||
params = self._prepare_params()
|
||||
response = self.client.get(f"/v1/memories/{memory_id}/", params=params)
|
||||
@@ -194,7 +205,12 @@ class MemoryClient:
|
||||
A list of dictionaries containing memories.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
"""
|
||||
params = self._prepare_params(kwargs)
|
||||
if version == "v1":
|
||||
@@ -236,7 +252,12 @@ class MemoryClient:
|
||||
A list of dictionaries containing search results.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
"""
|
||||
payload = {"query": query}
|
||||
params = self._prepare_params(kwargs)
|
||||
@@ -303,7 +324,12 @@ class MemoryClient:
|
||||
A dictionary containing the API response.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
"""
|
||||
params = self._prepare_params()
|
||||
response = self.client.delete(f"/v1/memories/{memory_id}/", params=params)
|
||||
@@ -323,7 +349,12 @@ class MemoryClient:
|
||||
A dictionary containing the API response.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
"""
|
||||
params = self._prepare_params(kwargs)
|
||||
response = self.client.delete("/v1/memories/", params=params)
|
||||
@@ -346,7 +377,12 @@ class MemoryClient:
|
||||
A list of dictionaries containing the memory history.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
"""
|
||||
params = self._prepare_params()
|
||||
response = self.client.get(f"/v1/memories/{memory_id}/history/", params=params)
|
||||
@@ -384,7 +420,10 @@ class MemoryClient:
|
||||
|
||||
Raises:
|
||||
ValueError: If specified entity not found
|
||||
APIError: If deletion fails
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
MemoryNotFoundError: If the entity doesn't exist.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
"""
|
||||
|
||||
if user_id:
|
||||
@@ -438,10 +477,13 @@ class MemoryClient:
|
||||
Dict[str, str]: Message client reset successful.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
"""
|
||||
# Delete all users, agents, and sessions
|
||||
# This will also delete the memories
|
||||
self.delete_users()
|
||||
|
||||
capture_client_event("client.reset", self, {"sync_type": "sync"})
|
||||
@@ -459,6 +501,14 @@ class MemoryClient:
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: The response from the server.
|
||||
|
||||
Raises:
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
"""
|
||||
response = self.client.put("/v1/batch/", json={"memories": memories})
|
||||
response.raise_for_status()
|
||||
@@ -479,7 +529,12 @@ class MemoryClient:
|
||||
str: Message indicating the success of the batch deletion.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
"""
|
||||
response = self.client.request("DELETE", "/v1/batch/", json={"memories": memories})
|
||||
response.raise_for_status()
|
||||
@@ -560,7 +615,12 @@ class MemoryClient:
|
||||
Dictionary containing the requested fields.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
logger.warning(
|
||||
@@ -604,7 +664,12 @@ class MemoryClient:
|
||||
Dictionary containing the API response.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
logger.warning(
|
||||
@@ -673,7 +738,12 @@ class MemoryClient:
|
||||
Dictionary containing webhook details.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
ValueError: If project_id is not set.
|
||||
"""
|
||||
|
||||
@@ -695,7 +765,12 @@ class MemoryClient:
|
||||
Dictionary containing the created webhook details.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
ValueError: If project_id is not set.
|
||||
"""
|
||||
|
||||
@@ -725,7 +800,12 @@ class MemoryClient:
|
||||
Dictionary containing the updated webhook details.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
"""
|
||||
|
||||
payload = {k: v for k, v in {"name": name, "url": url, "event_types": event_types}.items() if v is not None}
|
||||
@@ -745,7 +825,12 @@ class MemoryClient:
|
||||
Dictionary containing success message.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
"""
|
||||
|
||||
response = self.client.delete(f"api/v1/webhooks/{webhook_id}/")
|
||||
@@ -1098,7 +1183,12 @@ class AsyncMemoryClient:
|
||||
A dictionary containing the API response.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
"""
|
||||
params = self._prepare_params()
|
||||
response = await self.async_client.delete(f"/v1/memories/{memory_id}/", params=params)
|
||||
@@ -1117,7 +1207,12 @@ class AsyncMemoryClient:
|
||||
A dictionary containing the API response.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
"""
|
||||
params = self._prepare_params(kwargs)
|
||||
response = await self.async_client.delete("/v1/memories/", params=params)
|
||||
@@ -1136,7 +1231,12 @@ class AsyncMemoryClient:
|
||||
A list of dictionaries containing the memory history.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
"""
|
||||
params = self._prepare_params()
|
||||
response = await self.async_client.get(f"/v1/memories/{memory_id}/history/", params=params)
|
||||
@@ -1174,7 +1274,10 @@ class AsyncMemoryClient:
|
||||
|
||||
Raises:
|
||||
ValueError: If specified entity not found
|
||||
APIError: If deletion fails
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
MemoryNotFoundError: If the entity doesn't exist.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
"""
|
||||
|
||||
if user_id:
|
||||
@@ -1228,7 +1331,12 @@ class AsyncMemoryClient:
|
||||
Dict[str, str]: Message client reset successful.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
"""
|
||||
await self.delete_users()
|
||||
capture_client_event("client.reset", self, {"sync_type": "async"})
|
||||
@@ -1246,6 +1354,14 @@ class AsyncMemoryClient:
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: The response from the server.
|
||||
|
||||
Raises:
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
"""
|
||||
response = await self.async_client.put("/v1/batch/", json={"memories": memories})
|
||||
response.raise_for_status()
|
||||
@@ -1266,7 +1382,12 @@ class AsyncMemoryClient:
|
||||
str: Message indicating the success of the batch deletion.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
"""
|
||||
response = await self.async_client.request("DELETE", "/v1/batch/", json={"memories": memories})
|
||||
response.raise_for_status()
|
||||
@@ -1334,7 +1455,12 @@ class AsyncMemoryClient:
|
||||
Dictionary containing the requested fields.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
logger.warning(
|
||||
@@ -1374,7 +1500,12 @@ class AsyncMemoryClient:
|
||||
Dictionary containing the API response.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
logger.warning(
|
||||
@@ -1441,7 +1572,12 @@ class AsyncMemoryClient:
|
||||
Dictionary containing webhook details.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
ValueError: If project_id is not set.
|
||||
"""
|
||||
|
||||
@@ -1463,7 +1599,12 @@ class AsyncMemoryClient:
|
||||
Dictionary containing the created webhook details.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
ValueError: If project_id is not set.
|
||||
"""
|
||||
|
||||
@@ -1493,7 +1634,12 @@ class AsyncMemoryClient:
|
||||
Dictionary containing the updated webhook details.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
"""
|
||||
|
||||
payload = {k: v for k, v in {"name": name, "url": url, "event_types": event_types}.items() if v is not None}
|
||||
@@ -1513,7 +1659,12 @@ class AsyncMemoryClient:
|
||||
Dictionary containing success message.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
MemoryQuotaExceededError: If memory quota is exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
MemoryNotFoundError: If the memory doesn't exist (for updates/deletes).
|
||||
"""
|
||||
|
||||
response = await self.async_client.delete(f"api/v1/webhooks/{webhook_id}/")
|
||||
|
||||
+97
-24
@@ -7,6 +7,7 @@ from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
from mem0.client.utils import api_error_handler
|
||||
from mem0.memory.telemetry import capture_client_event
|
||||
# Exception classes are referenced in docstrings only
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -141,7 +142,10 @@ class BaseProject(ABC):
|
||||
Dictionary containing the requested project fields.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
pass
|
||||
@@ -159,7 +163,10 @@ class BaseProject(ABC):
|
||||
Dictionary containing the created project details.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
ValueError: If org_id is not set.
|
||||
"""
|
||||
pass
|
||||
@@ -185,7 +192,10 @@ class BaseProject(ABC):
|
||||
Dictionary containing the API response.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
pass
|
||||
@@ -199,7 +209,10 @@ class BaseProject(ABC):
|
||||
Dictionary containing the API response.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
pass
|
||||
@@ -213,7 +226,10 @@ class BaseProject(ABC):
|
||||
Dictionary containing the list of project members.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
pass
|
||||
@@ -231,7 +247,10 @@ class BaseProject(ABC):
|
||||
Dictionary containing the API response.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
pass
|
||||
@@ -249,7 +268,10 @@ class BaseProject(ABC):
|
||||
Dictionary containing the API response.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
pass
|
||||
@@ -266,7 +288,10 @@ class BaseProject(ABC):
|
||||
Dictionary containing the API response.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
pass
|
||||
@@ -310,7 +335,10 @@ class Project(BaseProject):
|
||||
Dictionary containing the requested project fields.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
params = self._prepare_params({"fields": fields})
|
||||
@@ -339,7 +367,10 @@ class Project(BaseProject):
|
||||
Dictionary containing the created project details.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
ValueError: If org_id is not set.
|
||||
"""
|
||||
if not self.config.org_id:
|
||||
@@ -382,7 +413,10 @@ class Project(BaseProject):
|
||||
Dictionary containing the API response.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
if (
|
||||
@@ -432,7 +466,10 @@ class Project(BaseProject):
|
||||
Dictionary containing the API response.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
response = self._client.delete(
|
||||
@@ -455,7 +492,10 @@ class Project(BaseProject):
|
||||
Dictionary containing the list of project members.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
response = self._client.get(
|
||||
@@ -482,7 +522,10 @@ class Project(BaseProject):
|
||||
Dictionary containing the API response.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
if role not in ["READER", "OWNER"]:
|
||||
@@ -515,7 +558,10 @@ class Project(BaseProject):
|
||||
Dictionary containing the API response.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
if role not in ["READER", "OWNER"]:
|
||||
@@ -547,7 +593,10 @@ class Project(BaseProject):
|
||||
Dictionary containing the API response.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
params = {"email": email}
|
||||
@@ -603,7 +652,10 @@ class AsyncProject(BaseProject):
|
||||
Dictionary containing the requested project fields.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
params = self._prepare_params({"fields": fields})
|
||||
@@ -632,7 +684,10 @@ class AsyncProject(BaseProject):
|
||||
Dictionary containing the created project details.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
ValueError: If org_id is not set.
|
||||
"""
|
||||
if not self.config.org_id:
|
||||
@@ -675,7 +730,10 @@ class AsyncProject(BaseProject):
|
||||
Dictionary containing the API response.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
if (
|
||||
@@ -725,7 +783,10 @@ class AsyncProject(BaseProject):
|
||||
Dictionary containing the API response.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
response = await self._client.delete(
|
||||
@@ -748,7 +809,10 @@ class AsyncProject(BaseProject):
|
||||
Dictionary containing the list of project members.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
response = await self._client.get(
|
||||
@@ -775,7 +839,10 @@ class AsyncProject(BaseProject):
|
||||
Dictionary containing the API response.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
if role not in ["READER", "OWNER"]:
|
||||
@@ -808,7 +875,10 @@ class AsyncProject(BaseProject):
|
||||
Dictionary containing the API response.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
if role not in ["READER", "OWNER"]:
|
||||
@@ -840,7 +910,10 @@ class AsyncProject(BaseProject):
|
||||
Dictionary containing the API response.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValidationError: If the input data is invalid.
|
||||
AuthenticationError: If authentication fails.
|
||||
RateLimitError: If rate limits are exceeded.
|
||||
NetworkError: If network connectivity issues occur.
|
||||
ValueError: If org_id or project_id are not set.
|
||||
"""
|
||||
params = {"email": email}
|
||||
|
||||
+91
-5
@@ -1,18 +1,35 @@
|
||||
import json
|
||||
import logging
|
||||
|
||||
import httpx
|
||||
|
||||
from mem0.exceptions import (
|
||||
NetworkError,
|
||||
create_exception_from_response,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class APIError(Exception):
|
||||
"""Exception raised for errors in the API."""
|
||||
"""Exception raised for errors in the API.
|
||||
|
||||
Deprecated: Use specific exception classes from mem0.exceptions instead.
|
||||
This class is maintained for backward compatibility.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
def api_error_handler(func):
|
||||
"""Decorator to handle API errors consistently."""
|
||||
"""Decorator to handle API errors consistently.
|
||||
|
||||
This decorator catches HTTP and request errors and converts them to
|
||||
appropriate structured exception classes with detailed error information.
|
||||
|
||||
The decorator analyzes HTTP status codes and response content to create
|
||||
the most specific exception type with helpful error messages, suggestions,
|
||||
and debug information.
|
||||
"""
|
||||
from functools import wraps
|
||||
|
||||
@wraps(func)
|
||||
@@ -21,9 +38,78 @@ def api_error_handler(func):
|
||||
return func(*args, **kwargs)
|
||||
except httpx.HTTPStatusError as e:
|
||||
logger.error(f"HTTP error occurred: {e}")
|
||||
raise APIError(f"API request failed: {e.response.text}")
|
||||
|
||||
# Extract error details from response
|
||||
response_text = ""
|
||||
error_details = {}
|
||||
debug_info = {
|
||||
"status_code": e.response.status_code,
|
||||
"url": str(e.request.url),
|
||||
"method": e.request.method,
|
||||
}
|
||||
|
||||
try:
|
||||
response_text = e.response.text
|
||||
# Try to parse JSON response for additional error details
|
||||
if e.response.headers.get("content-type", "").startswith("application/json"):
|
||||
error_data = json.loads(response_text)
|
||||
if isinstance(error_data, dict):
|
||||
error_details = error_data
|
||||
response_text = error_data.get("detail", response_text)
|
||||
except (json.JSONDecodeError, AttributeError):
|
||||
# Fallback to plain text response
|
||||
pass
|
||||
|
||||
# Add rate limit information if available
|
||||
if e.response.status_code == 429:
|
||||
retry_after = e.response.headers.get("Retry-After")
|
||||
if retry_after:
|
||||
try:
|
||||
debug_info["retry_after"] = int(retry_after)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
# Add rate limit headers if available
|
||||
for header in ["X-RateLimit-Limit", "X-RateLimit-Remaining", "X-RateLimit-Reset"]:
|
||||
value = e.response.headers.get(header)
|
||||
if value:
|
||||
debug_info[header.lower().replace("-", "_")] = value
|
||||
|
||||
# Create specific exception based on status code
|
||||
exception = create_exception_from_response(
|
||||
status_code=e.response.status_code,
|
||||
response_text=response_text,
|
||||
details=error_details,
|
||||
debug_info=debug_info,
|
||||
)
|
||||
|
||||
raise exception
|
||||
|
||||
except httpx.RequestError as e:
|
||||
logger.error(f"Request error occurred: {e}")
|
||||
raise APIError(f"Request failed: {str(e)}")
|
||||
|
||||
# Determine the appropriate exception type based on error type
|
||||
if isinstance(e, httpx.TimeoutException):
|
||||
raise NetworkError(
|
||||
message=f"Request timed out: {str(e)}",
|
||||
error_code="NET_TIMEOUT",
|
||||
suggestion="Please check your internet connection and try again",
|
||||
debug_info={"error_type": "timeout", "original_error": str(e)},
|
||||
)
|
||||
elif isinstance(e, httpx.ConnectError):
|
||||
raise NetworkError(
|
||||
message=f"Connection failed: {str(e)}",
|
||||
error_code="NET_CONNECT",
|
||||
suggestion="Please check your internet connection and try again",
|
||||
debug_info={"error_type": "connection", "original_error": str(e)},
|
||||
)
|
||||
else:
|
||||
# Generic network error for other request errors
|
||||
raise NetworkError(
|
||||
message=f"Network request failed: {str(e)}",
|
||||
error_code="NET_GENERIC",
|
||||
suggestion="Please check your internet connection and try again",
|
||||
debug_info={"error_type": "request", "original_error": str(e)},
|
||||
)
|
||||
|
||||
return wrapper
|
||||
|
||||
Reference in New Issue
Block a user