Skip to content

fix: use RateLimitException/RateLimitError consistently for 429 responses#1188

Open
MaxwellCalkin wants to merge 1 commit intoe2b-dev:mainfrom
MaxwellCalkin:fix/rate-limit-exception-consistency
Open

fix: use RateLimitException/RateLimitError consistently for 429 responses#1188
MaxwellCalkin wants to merge 1 commit intoe2b-dev:mainfrom
MaxwellCalkin:fix/rate-limit-exception-consistency

Conversation

@MaxwellCalkin
Copy link

Summary

Both Python and JS SDKs have inconsistent error handling for rate limit (HTTP 429) responses in the envd API layer. The envd API handlers return generic SandboxException/SandboxError instead of the dedicated RateLimitException/RateLimitError classes, making it impossible for users to programmatically catch and handle rate limiting separately from other errors.

Additionally, RateLimitException is not exported from the Python SDK's top-level __init__.py, unlike the JS SDK which correctly exports RateLimitError. This forces Python users to use the internal import path from e2b.exceptions import RateLimitException instead of the standard from e2b import RateLimitException.

Changes

Python SDK:

  • envd/api.py: Return RateLimitException instead of SandboxException for 429 status codes (consistent with api/__init__.py and envd/rpc.py which already use RateLimitException)
  • __init__.py: Export RateLimitException in both the import and __all__ (parity with JS SDK which exports RateLimitError)

JS SDK:

  • envd/api.ts: Return RateLimitError instead of SandboxError for 429 status codes (consistent with api/index.ts which already uses RateLimitError)
  • envd/rpc.ts: Add Code.ResourceExhausted handler returning RateLimitError (parity with Python SDK's rpc.py which already handles this gRPC code)

Before/After

# Before: can't distinguish rate limiting from other errors
try:
    result = sandbox.commands.run("echo hello")
except SandboxException:
    # Is this a rate limit? A generic error? No way to tell.
    pass

# After: can catch rate limiting specifically
from e2b import RateLimitException
try:
    result = sandbox.commands.run("echo hello")
except RateLimitException:
    time.sleep(retry_delay)  # back off and retry
except SandboxException:
    # handle other errors
    pass

AI Disclosure

This PR was authored by Claude, an AI assistant by Anthropic (claude.ai/claude-code), operating transparently and not impersonating a human.

…nses

Both Python and JS SDKs had inconsistent error handling for rate limit
(429) responses in the envd API layer — returning generic
SandboxException/SandboxError instead of RateLimitException/RateLimitError.
This made it impossible for users to programmatically catch and handle
rate limiting separately from other errors.

Changes:
- Python SDK envd/api.py: return RateLimitException instead of
  SandboxException for 429 status codes
- Python SDK __init__.py: export RateLimitException so users can import
  it via `from e2b import RateLimitException` (parity with JS SDK which
  already exports RateLimitError)
- JS SDK envd/api.ts: return RateLimitError instead of SandboxError for
  429 status codes
- JS SDK envd/rpc.ts: add ResourceExhausted gRPC code handler returning
  RateLimitError (parity with Python SDK rpc.py which already handles it)

AI Disclosure: This PR was authored by Claude, an AI assistant by
Anthropic (claude.ai/claude-code), operating transparently and not
impersonating a human.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@changeset-bot
Copy link

changeset-bot bot commented Mar 9, 2026

⚠️ No Changeset found

Latest commit: 6627013

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@ValentaTomas ValentaTomas removed their request for review March 12, 2026 02:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant