Documentation

Errors and Troubleshooting

Catch operation failures, handle asynchronous server errors, and diagnose common SDK problems.

Before you start: follow Connection and lifecycle. Register an error listener once per channel, and also catch exceptions from the operations that you await.

Every error that the SDK raises or reports is a CelerisError with a stable code. Match on the code, never on the message text. Messages name the field and the rule that failed. They never repeat your input, a credential, or server text.

1. Catch the operation you started

from useceleris_client import CelerisConnectionError, text_payload

try:
    await chat.publish(text_payload("Hello"))
except CelerisConnectionError as error:
    if error.code == "NotConnected":
        print("Wait until connected before sending.")
    else:
        print(error.code, error)

Catch connect(), publish(), and presence_list() where you await them. A failed initial connect raises to its caller and does not also reach on_error. The SDK likewise reports a failed presence query to its caller.

2. Handle server errors separately

from useceleris_client import ChannelError, ServerError


def handle(error: ChannelError) -> None:
    if not isinstance(error, ServerError):
        print(error.code, error)
        return

    print(error.type, error.sub_type, error)

    if error.type == "PermissionDeniedError":
        print("Check the server-issued channel and segment permissions.")
    elif error.type == "MessageSizeLimitError":
        print("Reduce the payload size.")
    elif error.type == "RateLimitError":
        # The SDK pauses and resends recent commands by itself.
        print("Rate limited; publish less often if this repeats.")
    else:
        print("The server reported an error.")


stop_errors = channel.events().on_error(handle)
# Later:
stop_errors()

A ServerError carries type, sub_type, its message, and resource. The sub_type is the command it answers, or None. The resource is what that command names, such as the segment. Its code is "Server". Error types are open-ended, so retain a default branch for a newer server. A resource can be None, a str, an int, or a tuple of these. Check its type before you use it.

A permission denial names a command and a segment. It does not identify which of several identical publishes caused the error. The SDK correlates presence-query errors internally. Those errors raise from presence_list() instead. Server error text is for people, not for programs. Show it as text, never as raw HTML. Server errors leave the connection open.

3. Choose the right response

codeResponse
ConfigurationFix the invalid argument or credential. A retry with unchanged input does not help
NotConnectedWait for a connection, then try again. A publish waits in the queue only while the channel is reconnecting
TimeoutCheck the credential endpoint and network, or the query deadline
CancelledThe channel closed during the operation. Do not automatically restart canceled work
TransportCheck network and credential setup. This does not prove an authentication failure. A listener that raised also reports Transport
BackpressureSlow production. The publish queue (publish_queue_size, 64 by default) is full, or a presence query found the writer full or paused
OperationInProgressDo not start simultaneous connects or presence queries on one channel
DeliveryUnknownAcceptance is uncertain. Do not blindly resend an irreversible operation
ProtocolErrorOne frame was dropped. The connection remains usable
ServerAn error from the server. See step 2

When you cancel a task that you own, the task raises asyncio.CancelledError, not an SDK error. The SDK isolates a listener's exception and reports it through on_error as a listener failure. Catch errors in the tasks that your listeners start.

4. Diagnose common symptoms

SymptomFirst checks
First connect fails and nothing retriesThis is expected. Call connect() again from failed
The channel stops in failed after a dropRead the last error from on_error. Recovery used all maximum_reconnect_attempts, or a failure that is not Transport or Timeout stopped it
Socket connects but messages are absentThe channel and segment names, a held subscription, and read permission
Sender sees no received copyallow_echo defaults to False
Publish returns, then an error arrivesExpected for server refusals. The return means only local acceptance
A listener registration raises ConfigurationErrorThe listener is an async def. Use a plain function that starts a task
Presence events miss a userYou get events only for joins and leaves while you hold presence. Query a cluster-wide listing
The server denied credentials, but the error says TransportThe handshake status is not available to the SDK
Messages are absent after recoveryReplay is bounded. Reload authoritative application state
Presence query raises ConfigurationUse int: page 1 to 2147483647 and per_page 1 to 100
A closed channel cannot reconnectObtain a new channel from the client

See Reconnection and Recovery for which failures retry. Do not run your own retry loop while the channel is in the reconnecting state.

Next: Server-side usage, or the Python client API for the full error surface.

We use Google cookies for analytics and for advertising measurement, only if you allow them. Until you choose, Google sets no cookies. Refer to our Cookie Policy.