repositories
loading repo index
repositories
loading repo index
repository
loading code, commits, and activity
public Clawd ADK gateway launch mirror
stars
latest
clone command
git clone gitlawb://did:key:z6Mkq5mY...iFZ5/my-project-publ...git clone gitlawb://did:key:z6Mkq5mY.../my-project-publ...2fa351d6docs: add automaton and perps launch sources16d ago| #1 | """Structured exception classes for Mem0 with error codes, suggestions, and debug information. |
| #2 | |
| #3 | This module provides a comprehensive set of exception classes that replace the generic |
| #4 | APIError with specific, actionable exceptions. Each exception includes error codes, |
| #5 | user-friendly suggestions, and debug information to enable better error handling |
| #6 | and recovery in applications using Mem0. |
| #7 | |
| #8 | Example: |
| #9 | Basic usage: |
| #10 | try: |
| #11 | memory.add(content, user_id=user_id) |
| #12 | except RateLimitError as e: |
| #13 | # Implement exponential backoff |
| #14 | time.sleep(e.debug_info.get('retry_after', 60)) |
| #15 | except MemoryQuotaExceededError as e: |
| #16 | # Trigger quota upgrade flow |
| #17 | logger.error(f"Quota exceeded: {e.error_code}") |
| #18 | except ValidationError as e: |
| #19 | # Return user-friendly error |
| #20 | raise HTTPException(400, detail=e.suggestion) |
| #21 | |
| #22 | Advanced usage with error context: |
| #23 | try: |
| #24 | memory.update(memory_id, content=new_content) |
| #25 | except MemoryNotFoundError as e: |
| #26 | logger.warning(f"Memory {memory_id} not found: {e.message}") |
| #27 | if e.suggestion: |
| #28 | logger.info(f"Suggestion: {e.suggestion}") |
| #29 | """ |
| #30 | |
| #31 | from typing import Any, Dict, Optional |
| #32 | |
| #33 | |
| #34 | class MemoryError(Exception): |
| #35 | """Base exception for all memory-related errors. |
| #36 | |
| #37 | This is the base class for all Mem0-specific exceptions. It provides a structured |
| #38 | approach to error handling with error codes, contextual details, suggestions for |
| #39 | resolution, and debug information. |
| #40 | |
| #41 | Attributes: |
| #42 | message (str): Human-readable error message. |
| #43 | error_code (str): Unique error identifier for programmatic handling. |
| #44 | details (dict): Additional context about the error. |
| #45 | suggestion (str): User-friendly suggestion for resolving the error. |
| #46 | debug_info (dict): Technical debugging information. |
| #47 | |
| #48 | Example: |
| #49 | raise MemoryError( |
| #50 | message="Memory operation failed", |
| #51 | error_code="MEM_001", |
| #52 | details={"operation": "add", "user_id": "user123"}, |
| #53 | suggestion="Please check your API key and try again", |
| #54 | debug_info={"request_id": "req_456", "timestamp": "2024-01-01T00:00:00Z"} |
| #55 | ) |
| #56 | """ |
| #57 | |
| #58 | def __init__( |
| #59 | self, |
| #60 | message: str, |
| #61 | error_code: str, |
| #62 | details: Optional[Dict[str, Any]] = None, |
| #63 | suggestion: Optional[str] = None, |
| #64 | debug_info: Optional[Dict[str, Any]] = None, |
| #65 | ): |
| #66 | """Initialize a MemoryError. |
| #67 | |
| #68 | Args: |
| #69 | message: Human-readable error message. |
| #70 | error_code: Unique error identifier. |
| #71 | details: Additional context about the error. |
| #72 | suggestion: User-friendly suggestion for resolving the error. |
| #73 | debug_info: Technical debugging information. |
| #74 | """ |
| #75 | self.message = message |
| #76 | self.error_code = error_code |
| #77 | self.details = details or {} |
| #78 | self.suggestion = suggestion |
| #79 | self.debug_info = debug_info or {} |
| #80 | super().__init__(self.message) |
| #81 | |
| #82 | def __repr__(self) -> str: |
| #83 | return ( |
| #84 | f"{self.__class__.__name__}(" |
| #85 | f"message={self.message!r}, " |
| #86 | f"error_code={self.error_code!r}, " |
| #87 | f"details={self.details!r}, " |
| #88 | f"suggestion={self.suggestion!r}, " |
| #89 | f"debug_info={self.debug_info!r})" |
| #90 | ) |
| #91 | |
| #92 | |
| #93 | class AuthenticationError(MemoryError): |
| #94 | """Raised when authentication fails. |
| #95 | |
| #96 | This exception is raised when API key validation fails, tokens are invalid, |
| #97 | or authentication credentials are missing or expired. |
| #98 | |
| #99 | Common scenarios: |
| #100 | - Invalid API key |
| #101 | - Expired authentication token |
| #102 | - Missing authentication headers |
| #103 | - Insufficient permissions |
| #104 | |
| #105 | Example: |
| #106 | raise AuthenticationError( |
| #107 | message="Invalid API key provided", |
| #108 | error_code="AUTH_001", |
| #109 | suggestion="Please check your API key in the Mem0 dashboard" |
| #110 | ) |
| #111 | """ |
| #112 | pass |
| #113 | |
| #114 | |
| #115 | class RateLimitError(MemoryError): |
| #116 | """Raised when rate limits are exceeded. |
| #117 | |
| #118 | This exception is raised when the API rate limit has been exceeded. |
| #119 | It includes information about retry timing and current rate limit status. |
| #120 | |
| #121 | The debug_info typically contains: |
| #122 | - retry_after: Seconds to wait before retrying |
| #123 | - limit: Current rate limit |
| #124 | - remaining: Remaining requests in current window |
| #125 | - reset_time: When the rate limit window resets |
| #126 | |
| #127 | Example: |
| #128 | raise RateLimitError( |
| #129 | message="Rate limit exceeded", |
| #130 | error_code="RATE_001", |
| #131 | suggestion="Please wait before making more requests", |
| #132 | debug_info={"retry_after": 60, "limit": 100, "remaining": 0} |
| #133 | ) |
| #134 | """ |
| #135 | pass |
| #136 | |
| #137 | |
| #138 | class ValidationError(MemoryError): |
| #139 | """Raised when input validation fails. |
| #140 | |
| #141 | This exception is raised when request parameters, memory content, |
| #142 | or configuration values fail validation checks. |
| #143 | |
| #144 | Common scenarios: |
| #145 | - Invalid user_id format |
| #146 | - Missing required fields |
| #147 | - Content too long or too short |
| #148 | - Invalid metadata format |
| #149 | - Malformed filters |
| #150 | |
| #151 | Example: |
| #152 | raise ValidationError( |
| #153 | message="Invalid user_id format", |
| #154 | error_code="VAL_001", |
| #155 | details={"field": "user_id", "value": "123", "expected": "string"}, |
| #156 | suggestion="User ID must be a non-empty string" |
| #157 | ) |
| #158 | """ |
| #159 | pass |
| #160 | |
| #161 | |
| #162 | class MemoryNotFoundError(MemoryError): |
| #163 | """Raised when a memory is not found. |
| #164 | |
| #165 | This exception is raised when attempting to access, update, or delete |
| #166 | a memory that doesn't exist or is not accessible to the current user. |
| #167 | |
| #168 | Example: |
| #169 | raise MemoryNotFoundError( |
| #170 | message="Memory not found", |
| #171 | error_code="MEM_404", |
| #172 | details={"memory_id": "mem_123", "user_id": "user_456"}, |
| #173 | suggestion="Please check the memory ID and ensure it exists" |
| #174 | ) |
| #175 | """ |
| #176 | pass |
| #177 | |
| #178 | |
| #179 | class NetworkError(MemoryError): |
| #180 | """Raised when network connectivity issues occur. |
| #181 | |
| #182 | This exception is raised for network-related problems such as |
| #183 | connection timeouts, DNS resolution failures, or service unavailability. |
| #184 | |
| #185 | Common scenarios: |
| #186 | - Connection timeout |
| #187 | - DNS resolution failure |
| #188 | - Service temporarily unavailable |
| #189 | - Network connectivity issues |
| #190 | |
| #191 | Example: |
| #192 | raise NetworkError( |
| #193 | message="Connection timeout", |
| #194 | error_code="NET_001", |
| #195 | suggestion="Please check your internet connection and try again", |
| #196 | debug_info={"timeout": 30, "endpoint": "api.mem0.ai"} |
| #197 | ) |
| #198 | """ |
| #199 | pass |
| #200 | |
| #201 | |
| #202 | class ConfigurationError(MemoryError): |
| #203 | """Raised when client configuration is invalid. |
| #204 | |
| #205 | This exception is raised when the client is improperly configured, |
| #206 | such as missing required settings or invalid configuration values. |
| #207 | |
| #208 | Common scenarios: |
| #209 | - Missing API key |
| #210 | - Invalid host URL |
| #211 | - Incompatible configuration options |
| #212 | - Missing required environment variables |
| #213 | |
| #214 | Example: |
| #215 | raise ConfigurationError( |
| #216 | message="API key not configured", |
| #217 | error_code="CFG_001", |
| #218 | suggestion="Set MEM0_API_KEY environment variable or pass api_key parameter" |
| #219 | ) |
| #220 | """ |
| #221 | pass |
| #222 | |
| #223 | |
| #224 | class MemoryQuotaExceededError(MemoryError): |
| #225 | """Raised when user's memory quota is exceeded. |
| #226 | |
| #227 | This exception is raised when the user has reached their memory |
| #228 | storage or usage limits. |
| #229 | |
| #230 | The debug_info typically contains: |
| #231 | - current_usage: Current memory usage |
| #232 | - quota_limit: Maximum allowed usage |
| #233 | - usage_type: Type of quota (storage, requests, etc.) |
| #234 | |
| #235 | Example: |
| #236 | raise MemoryQuotaExceededError( |
| #237 | message="Memory quota exceeded", |
| #238 | error_code="QUOTA_001", |
| #239 | suggestion="Please upgrade your plan or delete unused memories", |
| #240 | debug_info={"current_usage": 1000, "quota_limit": 1000, "usage_type": "memories"} |
| #241 | ) |
| #242 | """ |
| #243 | pass |
| #244 | |
| #245 | |
| #246 | class MemoryCorruptionError(MemoryError): |
| #247 | """Raised when memory data is corrupted. |
| #248 | |
| #249 | This exception is raised when stored memory data is found to be |
| #250 | corrupted, malformed, or otherwise unreadable. |
| #251 | |
| #252 | Example: |
| #253 | raise MemoryCorruptionError( |
| #254 | message="Memory data is corrupted", |
| #255 | error_code="CORRUPT_001", |
| #256 | details={"memory_id": "mem_123"}, |
| #257 | suggestion="Please contact support for data recovery assistance" |
| #258 | ) |
| #259 | """ |
| #260 | pass |
| #261 | |
| #262 | |
| #263 | class VectorSearchError(MemoryError): |
| #264 | """Raised when vector search operations fail. |
| #265 | |
| #266 | This exception is raised when vector database operations fail, |
| #267 | such as search queries, embedding generation, or index operations. |
| #268 | |
| #269 | Common scenarios: |
| #270 | - Embedding model unavailable |
| #271 | - Vector index corruption |
| #272 | - Search query timeout |
| #273 | - Incompatible vector dimensions |
| #274 | |
| #275 | Example: |
| #276 | raise VectorSearchError( |
| #277 | message="Vector search failed", |
| #278 | error_code="VEC_001", |
| #279 | details={"query": "find similar memories", "vector_dim": 1536}, |
| #280 | suggestion="Please try a simpler search query" |
| #281 | ) |
| #282 | """ |
| #283 | pass |
| #284 | |
| #285 | |
| #286 | class CacheError(MemoryError): |
| #287 | """Raised when caching operations fail. |
| #288 | |
| #289 | This exception is raised when cache-related operations fail, |
| #290 | such as cache misses, cache invalidation errors, or cache corruption. |
| #291 | |
| #292 | Example: |
| #293 | raise CacheError( |
| #294 | message="Cache operation failed", |
| #295 | error_code="CACHE_001", |
| #296 | details={"operation": "get", "key": "user_memories_123"}, |
| #297 | suggestion="Cache will be refreshed automatically" |
| #298 | ) |
| #299 | """ |
| #300 | pass |
| #301 | |
| #302 | |
| #303 | # OSS-specific exception classes |
| #304 | class VectorStoreError(MemoryError): |
| #305 | """Raised when vector store operations fail. |
| #306 | |
| #307 | This exception is raised when vector store operations fail, |
| #308 | such as embedding storage, similarity search, or vector operations. |
| #309 | |
| #310 | Example: |
| #311 | raise VectorStoreError( |
| #312 | message="Vector store operation failed", |
| #313 | error_code="VECTOR_001", |
| #314 | details={"operation": "search", "collection": "memories"}, |
| #315 | suggestion="Please check your vector store configuration and connection" |
| #316 | ) |
| #317 | """ |
| #318 | def __init__(self, message: str, error_code: str = "VECTOR_001", details: dict = None, |
| #319 | suggestion: str = "Please check your vector store configuration and connection", |
| #320 | debug_info: dict = None): |
| #321 | super().__init__(message, error_code, details, suggestion, debug_info) |
| #322 | |
| #323 | |
| #324 | class GraphStoreError(MemoryError): |
| #325 | """Raised when graph store operations fail. |
| #326 | |
| #327 | This exception is raised when graph store operations fail, |
| #328 | such as relationship creation, entity management, or graph queries. |
| #329 | |
| #330 | Example: |
| #331 | raise GraphStoreError( |
| #332 | message="Graph store operation failed", |
| #333 | error_code="GRAPH_001", |
| #334 | details={"operation": "create_relationship", "entity": "user_123"}, |
| #335 | suggestion="Please check your graph store configuration and connection" |
| #336 | ) |
| #337 | """ |
| #338 | def __init__(self, message: str, error_code: str = "GRAPH_001", details: dict = None, |
| #339 | suggestion: str = "Please check your graph store configuration and connection", |
| #340 | debug_info: dict = None): |
| #341 | super().__init__(message, error_code, details, suggestion, debug_info) |
| #342 | |
| #343 | |
| #344 | class EmbeddingError(MemoryError): |
| #345 | """Raised when embedding operations fail. |
| #346 | |
| #347 | This exception is raised when embedding operations fail, |
| #348 | such as text embedding generation or embedding model errors. |
| #349 | |
| #350 | Example: |
| #351 | raise EmbeddingError( |
| #352 | message="Embedding generation failed", |
| #353 | error_code="EMBED_001", |
| #354 | details={"text_length": 1000, "model": "openai"}, |
| #355 | suggestion="Please check your embedding model configuration" |
| #356 | ) |
| #357 | """ |
| #358 | def __init__(self, message: str, error_code: str = "EMBED_001", details: dict = None, |
| #359 | suggestion: str = "Please check your embedding model configuration", |
| #360 | debug_info: dict = None): |
| #361 | super().__init__(message, error_code, details, suggestion, debug_info) |
| #362 | |
| #363 | |
| #364 | class LLMError(MemoryError): |
| #365 | """Raised when LLM operations fail. |
| #366 | |
| #367 | This exception is raised when LLM operations fail, |
| #368 | such as text generation, completion, or model inference errors. |
| #369 | |
| #370 | Example: |
| #371 | raise LLMError( |
| #372 | message="LLM operation failed", |
| #373 | error_code="LLM_001", |
| #374 | details={"model": "gpt-4", "prompt_length": 500}, |
| #375 | suggestion="Please check your LLM configuration and API key" |
| #376 | ) |
| #377 | """ |
| #378 | def __init__(self, message: str, error_code: str = "LLM_001", details: dict = None, |
| #379 | suggestion: str = "Please check your LLM configuration and API key", |
| #380 | debug_info: dict = None): |
| #381 | super().__init__(message, error_code, details, suggestion, debug_info) |
| #382 | |
| #383 | |
| #384 | class DatabaseError(MemoryError): |
| #385 | """Raised when database operations fail. |
| #386 | |
| #387 | This exception is raised when database operations fail, |
| #388 | such as SQLite operations, connection issues, or data corruption. |
| #389 | |
| #390 | Example: |
| #391 | raise DatabaseError( |
| #392 | message="Database operation failed", |
| #393 | error_code="DB_001", |
| #394 | details={"operation": "insert", "table": "memories"}, |
| #395 | suggestion="Please check your database configuration and connection" |
| #396 | ) |
| #397 | """ |
| #398 | def __init__(self, message: str, error_code: str = "DB_001", details: dict = None, |
| #399 | suggestion: str = "Please check your database configuration and connection", |
| #400 | debug_info: dict = None): |
| #401 | super().__init__(message, error_code, details, suggestion, debug_info) |
| #402 | |
| #403 | |
| #404 | class DependencyError(MemoryError): |
| #405 | """Raised when required dependencies are missing. |
| #406 | |
| #407 | This exception is raised when required dependencies are missing, |
| #408 | such as optional packages for specific providers or features. |
| #409 | |
| #410 | Example: |
| #411 | raise DependencyError( |
| #412 | message="Required dependency missing", |
| #413 | error_code="DEPS_001", |
| #414 | details={"package": "kuzu", "feature": "graph_store"}, |
| #415 | suggestion="Please install the required dependencies: pip install kuzu" |
| #416 | ) |
| #417 | """ |
| #418 | def __init__(self, message: str, error_code: str = "DEPS_001", details: dict = None, |
| #419 | suggestion: str = "Please install the required dependencies", |
| #420 | debug_info: dict = None): |
| #421 | super().__init__(message, error_code, details, suggestion, debug_info) |
| #422 | |
| #423 | |
| #424 | # Mapping of HTTP status codes to specific exception classes |
| #425 | HTTP_STATUS_TO_EXCEPTION = { |
| #426 | 400: ValidationError, |
| #427 | 401: AuthenticationError, |
| #428 | 403: AuthenticationError, |
| #429 | 404: MemoryNotFoundError, |
| #430 | 408: NetworkError, |
| #431 | 409: ValidationError, |
| #432 | 413: MemoryQuotaExceededError, |
| #433 | 422: ValidationError, |
| #434 | 429: RateLimitError, |
| #435 | 500: MemoryError, |
| #436 | 502: NetworkError, |
| #437 | 503: NetworkError, |
| #438 | 504: NetworkError, |
| #439 | } |
| #440 | |
| #441 | |
| #442 | def create_exception_from_response( |
| #443 | status_code: int, |
| #444 | response_text: str, |
| #445 | error_code: Optional[str] = None, |
| #446 | details: Optional[Dict[str, Any]] = None, |
| #447 | debug_info: Optional[Dict[str, Any]] = None, |
| #448 | ) -> MemoryError: |
| #449 | """Create an appropriate exception based on HTTP response. |
| #450 | |
| #451 | This function analyzes the HTTP status code and response to create |
| #452 | the most appropriate exception type with relevant error information. |
| #453 | |
| #454 | Args: |
| #455 | status_code: HTTP status code from the response. |
| #456 | response_text: Response body text. |
| #457 | error_code: Optional specific error code. |
| #458 | details: Additional error context. |
| #459 | debug_info: Debug information. |
| #460 | |
| #461 | Returns: |
| #462 | An instance of the appropriate MemoryError subclass. |
| #463 | |
| #464 | Example: |
| #465 | exception = create_exception_from_response( |
| #466 | status_code=429, |
| #467 | response_text="Rate limit exceeded", |
| #468 | debug_info={"retry_after": 60} |
| #469 | ) |
| #470 | # Returns a RateLimitError instance |
| #471 | """ |
| #472 | exception_class = HTTP_STATUS_TO_EXCEPTION.get(status_code, MemoryError) |
| #473 | |
| #474 | # Generate error code if not provided |
| #475 | if not error_code: |
| #476 | error_code = f"HTTP_{status_code}" |
| #477 | |
| #478 | # Create appropriate suggestion based on status code |
| #479 | suggestions = { |
| #480 | 400: "Please check your request parameters and try again", |
| #481 | 401: "Please check your API key and authentication credentials", |
| #482 | 403: "You don't have permission to perform this operation", |
| #483 | 404: "The requested resource was not found", |
| #484 | 408: "Request timed out. Please try again", |
| #485 | 409: "Resource conflict. Please check your request", |
| #486 | 413: "Request too large. Please reduce the size of your request", |
| #487 | 422: "Invalid request data. Please check your input", |
| #488 | 429: "Rate limit exceeded. Please wait before making more requests", |
| #489 | 500: "Internal server error. Please try again later", |
| #490 | 502: "Service temporarily unavailable. Please try again later", |
| #491 | 503: "Service unavailable. Please try again later", |
| #492 | 504: "Gateway timeout. Please try again later", |
| #493 | } |
| #494 | |
| #495 | suggestion = suggestions.get(status_code, "Please try again later") |
| #496 | |
| #497 | return exception_class( |
| #498 | message=response_text or f"HTTP {status_code} error", |
| #499 | error_code=error_code, |
| #500 | details=details or {}, |
| #501 | suggestion=suggestion, |
| #502 | debug_info=debug_info or {}, |
| #503 | ) |