diff --git a/docs/sandbox.md b/docs/sandbox.md index 7aef7af3..80705d9e 100644 --- a/docs/sandbox.md +++ b/docs/sandbox.md @@ -2143,6 +2143,16 @@ class SandboxTimeoutError(SandboxError) Raised when a sandbox operation times out + + +## SandboxDeploymentError Objects + +```python +class SandboxDeploymentError(SandboxError) +``` + +Raised when a sandbox deployment reaches an error state + # koyeb/sandbox.executor\_client diff --git a/koyeb/sandbox/__init__.py b/koyeb/sandbox/__init__.py index e3106218..b4b3d58a 100644 --- a/koyeb/sandbox/__init__.py +++ b/koyeb/sandbox/__init__.py @@ -17,7 +17,7 @@ ) from .filesystem import FileInfo, SandboxFilesystem from .sandbox import AsyncSandbox, ExposedPort, ProcessInfo, Sandbox -from .utils import SandboxError, SandboxTimeoutError +from .utils import SandboxDeploymentError, SandboxError, SandboxTimeoutError __all__ = [ "Sandbox", @@ -27,6 +27,7 @@ "AsyncSandboxExecutor", "FileInfo", "SandboxStatus", + "SandboxDeploymentError", "SandboxError", "SandboxTimeoutError", "CommandResult", diff --git a/koyeb/sandbox/sandbox.py b/koyeb/sandbox/sandbox.py index 7213d628..aa9cb6d4 100644 --- a/koyeb/sandbox/sandbox.py +++ b/koyeb/sandbox/sandbox.py @@ -24,6 +24,7 @@ from .utils import ( DEFAULT_INSTANCE_WAIT_TIMEOUT, DEFAULT_POLL_INTERVAL, + SandboxDeploymentError, SandboxError, SandboxTimeoutError, async_wrapper, @@ -388,12 +389,20 @@ def get_from_id( sandbox_secret=sandbox_secret, ) + _DEPLOYMENT_ERROR_STATUSES = { + DeploymentStatus.ERROR, + DeploymentStatus.ERRORING, + } + def _is_deployment_healthy(self) -> bool: """ Check if the sandbox deployment status is HEALTHY via the API. Returns: bool: True if the deployment status is HEALTHY, False otherwise + + Raises: + SandboxDeploymentError: If the deployment has reached a terminal error state """ try: _, services_api, _, _, deployments_api = get_api_client(self.api_token) @@ -404,7 +413,14 @@ def _is_deployment_healthy(self) -> bool: return False deployment_response = deployments_api.get_deployment(deployment_id) status = deployment_response.deployment.status + if status in self._DEPLOYMENT_ERROR_STATUSES: + raise SandboxDeploymentError( + f"Sandbox '{self.name}' deployment reached status {status.value}. " + f"The sandbox will not become ready." + ) return status == DeploymentStatus.HEALTHY + except SandboxDeploymentError: + raise except Exception: return False diff --git a/koyeb/sandbox/utils.py b/koyeb/sandbox/utils.py index dd1d46b5..0b942b31 100644 --- a/koyeb/sandbox/utils.py +++ b/koyeb/sandbox/utils.py @@ -486,3 +486,7 @@ class SandboxError(Exception): class SandboxTimeoutError(SandboxError): """Raised when a sandbox operation times out""" + + +class SandboxDeploymentError(SandboxError): + """Raised when a sandbox deployment reaches an error state"""