Skip to content

sdk-drift: NetworkError and ExchangeNotAvailable have retryable=True in TypeScript but retryable=False (default) in Python #831

@realfishsam

Description

@realfishsam

Drift

NetworkError and ExchangeNotAvailable are explicitly constructed with retryable: true in the TypeScript SDK. The Python equivalents inherit from PmxtError with no override, leaving retryable at the base-class default of False. Code that branches on error.retryable to decide whether to retry a request will behave differently depending on which SDK is in use.

TypeScript SDK

sdks/typescript/pmxt/errors.ts:

// line 108–111
export class NetworkError extends PmxtError {
    constructor(message: string, exchange?: string) {
        super(message, "NETWORK_ERROR", true, exchange);  // retryable = true
    }
}

// line 113–117
export class ExchangeNotAvailable extends PmxtError {
    constructor(message: string, exchange?: string) {
        super(message, "EXCHANGE_NOT_AVAILABLE", true, exchange);  // retryable = true
    }
}

Python SDK

sdks/python/pmxt/errors.py:

# line 95–103
class NetworkError(PmxtError):
    """503 Service Unavailable - Network connectivity issues."""
    pass  # no retryable override → inherits retryable=False from PmxtError.__init__

class ExchangeNotAvailable(PmxtError):
    """503 Service Unavailable - Exchange is down or unreachable."""
    pass  # no retryable override → inherits retryable=False from PmxtError.__init__

PmxtError.__init__ signature (line 16): def __init__(self, message: str, code: str = "UNKNOWN_ERROR", retryable: bool = False, ...) — default is False.

Expected

Both NetworkError and ExchangeNotAvailable should have retryable=True in Python, matching the TypeScript SDK:

class NetworkError(PmxtError):
    def __init__(self, message: str, **kwargs):
        super().__init__(message, code="NETWORK_ERROR", retryable=True, **kwargs)

class ExchangeNotAvailable(PmxtError):
    def __init__(self, message: str, **kwargs):
        super().__init__(message, code="EXCHANGE_NOT_AVAILABLE", retryable=True, **kwargs)

Impact

Any retry logic that inspects error.retryable (e.g., exponential back-off wrappers, middleware, user code) will silently skip retries for network and availability errors in Python while correctly retrying in TypeScript. This is a silent behavioral divergence for users who port retry logic between the two SDKs.


Found by automated SDK cross-language drift audit

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions