WebSocket Error Handling
Error handling in WebSocket applications is essential for building a robust, predictable real-time experience. Since WebSockets are persistent and event-driven, your system must clearly communicate both protocol-level and application-level errors.
This page covers error categories, message formats, best practices, and how to gracefully handle failures.
โ 1. Types of Errors
Type | Description | Examples |
---|---|---|
Connection-level | Issues during connection or handshake | Invalid auth token, unsupported path |
Application-level | Errors in event logic or payload processing | Invalid room ID, permission denied |
Transport-level | Network failures, client disconnects, timeouts | Lost connection, ping timeout |
๐งฑ 2. Error Message Format
Your application should return errors in a consistent JSON structure:
{
"type": "error",
"data": {
"code": 4001,
"message": "Room not found"
},
"meta": {
"request_id": "abc-123",
"timestamp": "2025-08-04T12:00:00Z"
}
}
Field Definitions
Field | Description |
---|---|
type |
Always "error" |
data.code |
Numeric error code |
data.message |
Human-readable error message |
meta |
Optional context (timestamp, request ID) |
๐ข 3. Custom Error Codes
Code | Meaning | Use Case |
---|---|---|
4000 |
Bad request | Malformed JSON or missing fields |
4001 |
Not found | Room, user, or resource not found |
4002 |
Invalid action | Sending message to closed room |
4003 |
Unauthorized | Token missing or expired |
4004 |
Forbidden | User lacks permission |
4005 |
Rate limited | Too many requests |
5000 |
Internal server error | Unexpected backend failure |
๐จ 4. Closing with Errors
If a critical error requires closing the connection, send an error
message first, then close:
Server:
Then:
Clients should listen for both message
and close
events.
๐ 5. Client Handling Example (JavaScript)
socket.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type === "error") {
console.error(`[WebSocket Error] ${msg.data.code}: ${msg.data.message}`);
alert("Something went wrong: " + msg.data.message);
}
};
socket.onclose = (event) => {
if (event.code === 4003) {
alert("You were disconnected due to authentication failure.");
}
};
โ 6. Best Practices
- Use structured error responses with consistent codes.
- Never expose stack traces or internals in messages.
- Log all server-side errors with context and traceback.
- Differentiate between recoverable and fatal errors.
- Allow clients to retry or reconnect after soft failures.
๐งช 7. Testing Your Error Handling
- Simulate invalid messages (e.g., bad JSON, unknown
type
). - Force auth failures (e.g., expired tokens).
- Disconnect network mid-session.
- Exceed rate limits to test throttling responses.
- Monitor logs for uncaught exceptions.
๐ Next Steps
- Connection Events: Handle connection-related failures.
- Authentication: Prevent errors before accepting a socket.
- Clients: Build fault-tolerant frontends.