initial commit

This commit is contained in:
2026-05-11 12:36:20 +05:30
commit 384cbe8019
15377 changed files with 2360544 additions and 0 deletions

View File

@@ -0,0 +1,286 @@
"""Custom exceptions for the sandbox client.
All sandbox exceptions extend LangSmithError for unified error handling.
The exceptions are organized by error type rather than resource type,
with a resource_type attribute for specific handling when needed.
"""
from __future__ import annotations
from typing import Optional
from langsmith.utils import LangSmithError
class SandboxClientError(LangSmithError):
"""Base exception for sandbox client errors."""
pass
# =============================================================================
# Connection and Authentication Errors
# =============================================================================
class SandboxAPIError(SandboxClientError):
"""Raised when the API endpoint returns an unexpected error.
For example, this is raised for wrong URL or path.
"""
pass
class SandboxAuthenticationError(SandboxClientError):
"""Raised when authentication fails (invalid or missing API key)."""
pass
class SandboxConnectionError(SandboxClientError):
"""Raised when connection to the sandbox server fails."""
pass
class SandboxServerReloadError(SandboxConnectionError):
"""Raised when the server sends a 1001 Going Away close frame.
This indicates a server hot-reload, not a true connection failure.
The command is still running on the server.
This is a subclass of SandboxConnectionError, so the auto-reconnect
logic in CommandHandle catches it along with all other
connection errors. The distinction matters for retry strategy:
SandboxServerReloadError triggers immediate reconnect (no backoff),
while other SandboxConnectionError triggers exponential backoff.
Users typically never see this exception — it's handled internally.
"""
pass
# =============================================================================
# Resource Errors (type-based, with resource_type attribute)
# =============================================================================
class ResourceNotFoundError(SandboxClientError):
"""Raised when a resource is not found.
Attributes:
resource_type: Type of resource (sandbox, template, volume, pool, file).
"""
def __init__(self, message: str, resource_type: Optional[str] = None):
"""Initialize the error."""
super().__init__(message)
self.resource_type = resource_type
class ResourceTimeoutError(SandboxClientError):
"""Raised when an operation times out.
Attributes:
resource_type: Type of resource (sandbox, volume, pool).
last_status: The last known status before timeout (for sandboxes).
"""
def __init__(
self,
message: str,
resource_type: Optional[str] = None,
last_status: Optional[str] = None,
):
"""Initialize the error."""
super().__init__(message)
self.resource_type = resource_type
self.last_status = last_status
def __str__(self) -> str:
"""Return string representation."""
base = super().__str__()
if self.last_status:
return f"{base} (last_status: {self.last_status})"
return base
class ResourceInUseError(SandboxClientError):
"""Raised when deleting a resource that is still in use.
Attributes:
resource_type: Type of resource (template, volume).
"""
def __init__(self, message: str, resource_type: Optional[str] = None):
"""Initialize the error."""
super().__init__(message)
self.resource_type = resource_type
class ResourceAlreadyExistsError(SandboxClientError):
"""Raised when creating a resource that already exists.
Attributes:
resource_type: Type of resource (e.g., pool).
"""
def __init__(self, message: str, resource_type: Optional[str] = None):
"""Initialize the error."""
super().__init__(message)
self.resource_type = resource_type
class ResourceNameConflictError(SandboxClientError):
"""Raised when updating a resource name to one that already exists.
Attributes:
resource_type: Type of resource (volume, template, pool, sandbox).
"""
def __init__(self, message: str, resource_type: Optional[str] = None):
"""Initialize the error."""
super().__init__(message)
self.resource_type = resource_type
# =============================================================================
# Validation and Quota Errors
# =============================================================================
class ValidationError(SandboxClientError):
"""Raised when request validation fails.
This includes:
- Resource values exceeding server-defined limits (CPU, memory, storage)
- Invalid resource units
- Invalid name formats
- Pool validation failures (e.g., template has volumes)
Attributes:
field: The field that failed validation (e.g., "cpu", "memory").
details: List of validation error details from the API.
error_type: Machine-readable error type from the API.
"""
def __init__(
self,
message: str,
field: Optional[str] = None,
details: Optional[list[dict]] = None,
error_type: Optional[str] = None,
):
"""Initialize the error."""
super().__init__(message)
self.field = field
self.details = details or []
self.error_type = error_type
class QuotaExceededError(SandboxClientError):
"""Raised when organization quota limits are exceeded.
Users should contact support@langchain.dev to increase quotas.
Attributes:
quota_type: Type of quota exceeded (e.g., "sandbox_count", "cpu").
"""
def __init__(self, message: str, quota_type: Optional[str] = None):
"""Initialize the error."""
super().__init__(message)
self.quota_type = quota_type
# =============================================================================
# Resource Creation Errors
# =============================================================================
class ResourceCreationError(SandboxClientError):
"""Raised when resource provisioning fails.
Attributes:
resource_type: Type of resource (sandbox, volume, pool).
error_type: Machine-readable error type (ImagePull, CrashLoop,
SandboxConfig, Unschedulable, VolumeProvisioning).
"""
def __init__(
self,
message: str,
resource_type: Optional[str] = None,
error_type: Optional[str] = None,
):
"""Initialize the error."""
super().__init__(message)
self.resource_type = resource_type
self.error_type = error_type
def __str__(self) -> str:
"""Return string representation."""
if self.error_type:
return f"{super().__str__()} [{self.error_type}]"
return super().__str__()
# =============================================================================
# Sandbox Operation Errors (runtime errors during sandbox interaction)
# =============================================================================
class DataplaneNotConfiguredError(SandboxClientError):
"""Raised when dataplane_url is not available for the sandbox.
This occurs when the sandbox-router URL is not configured for the cluster.
"""
pass
class SandboxNotReadyError(SandboxClientError):
"""Raised when attempting to interact with a sandbox that is not ready."""
pass
class SandboxOperationError(SandboxClientError):
"""Raised when a sandbox operation fails (run, read, write).
Attributes:
operation: The operation that failed (command, read, write).
error_type: Machine-readable error type from the API.
"""
def __init__(
self,
message: str,
operation: Optional[str] = None,
error_type: Optional[str] = None,
):
"""Initialize the error."""
super().__init__(message)
self.operation = operation
self.error_type = error_type
def __str__(self) -> str:
"""Return string representation."""
if self.error_type:
return f"{super().__str__()} [{self.error_type}]"
return super().__str__()
class CommandTimeoutError(SandboxOperationError):
"""Raised when a command exceeds its timeout.
Attributes:
timeout: The timeout value in seconds that was exceeded.
"""
def __init__(self, message: str, timeout: Optional[int] = None):
"""Initialize the error."""
super().__init__(message, operation="command", error_type="CommandTimeout")
self.timeout = timeout