使用BaleBot发送PhotoMessage时Socket断开,空错误如何解决?
Problem Scenario
I'm trying to send a PhotoMessage, but the socket disconnects mid-send. When the promise's catch callback triggers, it returns an empty/undefined error, making it hard to diagnose the root cause. Here's the relevant log output:
[2018-05-07 13:31:40.432] [TRACE] [default] - Sending on socket: {"$type":"Request","id":"3","service":"messaging","body":{"$type":"SendMessage","peer":{"$type":"User","id":XXX,"accessHash":"YYY"},"randomId":"796200377717532288","message":{"$type":"Document","fileId":"-5218264593238523391","accessHash":6687875,"fileSize":"157727","name":"871073.jpg","mimeType":"image/jpg","thumb":{},"ext":{"$type":"Photo"},"caption":{"$type":"Text","text":"test"},"checkSum":"checkSum","algorithm":"algorithm","fileStorageVersion":1}}} [2018-05-07 13:31:40.435] [TRACE] [default] - send callback: err: undefined [2018-05-07 13:31:43.221] [INFO] [default] - Connecting... [2018-05-07 13:31:43.913] [INFO] [default] - Socket Connected!
Root Cause Analysis
Looking at the logs, the socket disconnects immediately after sending the request (3ms later), but your error handling logic isn't capturing the actual disconnect reason—hence the undefined error. Common triggers here include:
- Network flakiness causing unexpected TCP drops
- Server-side rejection (e.g., invalid
thumbparameter, which is empty in your request) - Missing error listeners on the socket instance, so disconnect events aren't propagated to your promise
Fix Steps
1. Fix Error Capturing to Avoid Undefined Errors
Your promise is likely only catching explicit promise rejections, not socket-level errors. Add listeners to the socket's error and close events to capture disconnect details and pass them to your promise's reject handler:
// Before sending the message, attach error/close listeners let currentSendPromise; function sendPhotoMessage(messageData) { return new Promise((resolve, reject) => { currentSendPromise = { reject }; // Capture socket errors socket.once('error', (err) => { reject(new Error(`Socket error: ${err.message || 'Unknown error'}`)); currentSendPromise = null; }); // Capture socket disconnect details socket.once('close', (code, reason) => { if (currentSendPromise) { reject(new Error(`Socket closed: Code ${code}, Reason: ${reason || 'No reason provided'}`)); currentSendPromise = null; } }); // Send your message as before socket.send(JSON.stringify(messageData), (err) => { if (err) reject(err); else resolve(); }); }); }
This ensures you'll get a meaningful error message instead of undefined.
2. Validate Request Parameters
Your log shows thumb: {}—many messaging services require a valid thumbnail object (with dimensions, file data, or a valid reference) for photo messages. An empty thumbnail might cause the server to reject the request and terminate the socket. Check the service's API docs to confirm the required thumb structure and populate it correctly.
3. Add Retry Logic for Post-Reconnection
Since your logs show the socket reconnects successfully 3 seconds later, add a retry mechanism to resend the message once the socket is back online. Make sure to use a new randomId to avoid duplicate messages:
let pendingMessage; // Trigger retry on successful reconnection socket.on('connect', () => { if (pendingMessage) { // Generate a new unique random ID to prevent duplicate messages pendingMessage.randomId = BigInt(Math.floor(Math.random() * 1e18)).toString(); sendPhotoMessage(pendingMessage).catch(err => console.error('Retry failed:', err)); pendingMessage = null; } }); // Store failed messages for retry sendPhotoMessage(yourMessageData).catch(err => { if (err.message.includes('Socket closed')) { pendingMessage = yourMessageData; console.log('Message pending retry on reconnection'); } else { console.error('Send failed:', err); } });
4. Enhance Logging for Debugging
Add more detailed logging to track socket state changes and request lifecycle:
socket.on('connecting', () => console.log('[DEBUG] Socket connecting...')); socket.on('connect', () => console.log('[DEBUG] Socket connected successfully')); socket.on('disconnect', () => console.log('[DEBUG] Socket disconnected')); socket.on('error', (err) => console.error('[DEBUG] Socket error:', err));
This will give you clearer visibility into when and why the socket drops.
内容的提问来源于stack exchange,提问作者javad adel

