Problem
Both handlers in lib/drivers/driver.ts destructure fields.args with no guard:
onMessage = (cb: ICallback): void => {
this.socket.on('stream-room-messages', ({ fields: { args: [message] } }: any) => cb(this.ejsonMessage(message)))
}
onTyping = (cb: ICallback): Promise<any> => {
return this.socket.on('stream-notify-room', ({ fields: { args: [username, isTyping] } }: any) => {
cb(username, isTyping)
}) as any
}
Any frame on stream-room-messages or stream-notify-room that arrives without fields, or with fields but no args, throws a TypeError from inside the socket's emit. The throw happens on the emit path, so it does not surface as a rejected promise the caller can catch — it propagates out of whatever drove the emit.
onTyping also declares Promise<any> and casts the listener registration as any; it returns the emitter, not a promise.
Note
Verify if these callbacks are actually used in the mobile app before working. I'm pretty sure they don't use them and instead they use the streams directly.
Steps to reproduce
- Connect a driver and register
onMessage
- Have the server (or a fake transport) deliver a
changed frame on stream-room-messages whose fields has no args
- Observe the
TypeError thrown from the emit rather than being handled
Proposed fix
Guard both handlers and drop the frame when the payload shape is not what the stream promises, rather than throwing. Decide explicitly whether a malformed frame should be logged at error — the driver has a logger for this.
Note for whoever picks this up: a test must not simply pin today's throw, since that would freeze the crash as intended behaviour. The fix comes first, then the test asserts the frame is dropped.
Problem
Both handlers in
lib/drivers/driver.tsdestructurefields.argswith no guard:Any frame on
stream-room-messagesorstream-notify-roomthat arrives withoutfields, or withfieldsbut noargs, throws aTypeErrorfrom inside the socket'semit. The throw happens on the emit path, so it does not surface as a rejected promise the caller can catch — it propagates out of whatever drove the emit.onTypingalso declaresPromise<any>and casts the listener registrationas any; it returns the emitter, not a promise.Note
Verify if these callbacks are actually used in the mobile app before working. I'm pretty sure they don't use them and instead they use the streams directly.
Steps to reproduce
onMessagechangedframe onstream-room-messageswhosefieldshas noargsTypeErrorthrown from the emit rather than being handledProposed fix
Guard both handlers and drop the frame when the payload shape is not what the stream promises, rather than throwing. Decide explicitly whether a malformed frame should be logged at
error— the driver has a logger for this.Note for whoever picks this up: a test must not simply pin today's throw, since that would freeze the crash as intended behaviour. The fix comes first, then the test asserts the frame is dropped.