Diagnose authorization, transport, rate-limit, and SDK failures.
Errors
Errors surface through the WebSocket connection, subscribed channels, and backend SDK requests.
Handle Channel Errors
Use onRawEvent to receive errors associated with an established WebSocket connection:
const channel = edge.channel("private:user-123");
channel.onRawEvent((event) => {
if (event.type === "server.error") {
switch (event.code) {
case "authorization.subscribe_denied":
showAccessDenied();
break;
case "rate_limit.exceeded":
scheduleRetry();
break;
default:
reportError(event);
}
}
});
channel.subscribe("notification.created", onNotification);A server.error event has this shape:
{
type: "server.error";
channel?: string;
code: EdgeErrorCode;
message: string;
nodeId?: string;
serverTime?: string;
}Use code for application logic. message is diagnostic text and may become more specific without a protocol-breaking change.
EdgeErrorCode is exported from @seuraa/edge.
Authorization Errors
| Code | Message | Emitted when |
|---|---|---|
authorization.subscribe_denied | subscribe is not authorized | A channel token does not authorize a subscription. |
authorization.publish_denied | publish is not authorized | A channel token does not authorize an event publish. |
channel.not_subscribed | channel is not subscribed | A publish targets a channel that is not subscribed on the connection. |
For an authorization denial, check:
- An expired, revoked, malformed, or incorrectly signed token.
- A token issued for another app or channel.
- A user identity mismatch.
- A missing subscribe or publish permission.
- An event name excluded by the token's
publish:<event>permissions. - Missing identity claims for private or presence channels.
Rate And Capacity Errors
| Surface | Signal | Behavior |
|---|---|---|
| Channel operation | server.error with code rate_limit.exceeded | The operation is rejected. The connection remains available. |
| Server-side publish | Rejected promise containing HTTP status 429 | The event is not accepted. |
| WebSocket connection | Failed upgrade | The connection is not established. |
| Channel operation | server.error with code rate_limit.unavailable | The operation is rejected because rate-limit state could not be checked. |
For a refused WebSocket upgrade, use onStatus for connection state and inspect browser network diagnostics for the HTTP response.
Payload And Protocol Errors
| Code or status | Emitted when | Connection behavior |
|---|---|---|
payload.too_large | A complete WebSocket frame exceeds the configured maximum. | The connection closes after the error. |
HTTP 413 with request is too large | A backend SDK request exceeds the configured maximum. | Not applicable. |
protocol.invalid | A client frame cannot be decoded. | The connection remains available. |
protocol.unsupported | A decoded frame contains no supported operation. | The connection remains available. |
event.name_required | A publish has no event name. | The connection remains available. |
channel.required | A channel operation has no channel name. | The connection remains available. |
channel.invalid | A channel name has an unsupported class, character, or length. | The connection remains available. |
Connection And Transport State
Use onStatus to observe connection state:
channel.onStatus((event) => {
if (event.status === "error") {
console.error("Seuraa connection error");
}
});| Operation | Signal | Meaning |
|---|---|---|
| Connection | Status changes to error. | The connection encountered a transport or protocol failure. |
| Reconnection | Status changes to retrying. | The connection closed unexpectedly and a reconnect is scheduled with backoff. |
| Publish | channel.publish(...) returns { sent: false }. | The event was not sent because the WebSocket was unavailable. |
Status events describe connection lifecycle. Publish results describe that publish attempt. Accepted publishes are confirmed separately by publish.accepted.
onDebug provides additional diagnostic context, but it is not an error-handling API.
Backend SDK Errors
Backend SDK network methods reject their promises for non-success responses:
try {
await edge.channels.publish(channel, eventName, data);
} catch (error) {
console.error(error);
}| Method | Rejection format |
|---|---|
edge.channels.publish(...) | edge publish failed with status <status> |
edge.channels.presence(...) | edge presence failed with status <status>: <response body> |
edge.auth.revoke(...) | edge token revocation failed with status <status>: <response body> |
Common HTTP statuses:
| Status | Returned when |
|---|---|
400 | JSON is invalid, required input is missing, or a channel name is invalid. |
401 | The app key and signed request do not match. |
403 | App authentication is not configured for the requested operation. |
405 | The endpoint received an unsupported HTTP method. |
413 | The request body exceeds the configured maximum. |
429 | The app exceeded a configured rate limit. |
503 | The operation could not be served at that time. |
Troubleshooting
Choose retry behavior according to the operation and your application's delivery requirements. Before retrying, inspect:
- The error code or HTTP status.
- Whether the original operation was accepted.
- Whether repeating the operation is idempotent.
- Token expiry and authorization state.
- Current connection status.
- The
clientEventIdfor publish attempts.
Unexpected Errors
Log the complete error event or rejected Error, including its code, channel, timestamp, and nodeId when available.
Error Codes
type EdgeErrorCode =
| "authorization.publish_denied"
| "authorization.subscribe_denied"
| "channel.not_subscribed"
| "channel.invalid"
| "channel.required"
| "event.name_required"
| "payload.too_large"
| "protocol.invalid"
| "protocol.unsupported"
| "rate_limit.exceeded"
| "rate_limit.unavailable"
| "service.unavailable";service.unavailable indicates a temporary service failure.