@@ -88,6 +88,39 @@ function getChannel(channelName: string): PusherChannel | undefined {
88
88
return socket . getChannel ( channelName ) ;
89
89
}
90
90
91
+ /**
92
+ * Parses JSON data that may be single or double-encoded
93
+ * This handles cases where the backend sometimes sends double-encoded JSON
94
+ * Reference issue: https://github.com/Expensify/App/issues/60332
95
+ */
96
+ function parseEventData < EventName extends PusherEventName > ( eventData : EventData < EventName > ) : EventData < EventName > | null {
97
+ if ( isObject ( eventData ) ) {
98
+ return eventData ;
99
+ }
100
+
101
+ if ( typeof eventData !== 'string' ) {
102
+ Log . alert ( '[Pusher] Event data is neither object nor string' , { eventData} ) ;
103
+ return null ;
104
+ }
105
+
106
+ try {
107
+ const firstParse = JSON . parse ( eventData ) as EventData < EventName > | string ;
108
+
109
+ // If result is still a string, it was double-encoded - parse again
110
+ if ( typeof firstParse === 'string' ) {
111
+ return JSON . parse ( firstParse ) as EventData < EventName > ;
112
+ }
113
+
114
+ return firstParse ;
115
+ } catch ( error ) {
116
+ Log . alert ( '[Pusher] Failed to parse event data' , {
117
+ error : error instanceof Error ? error . message : 'Unknown error' ,
118
+ eventData,
119
+ } ) ;
120
+ return null ;
121
+ }
122
+ }
123
+
91
124
/**
92
125
* Binds an event callback to a channel + eventName
93
126
*/
@@ -103,11 +136,9 @@ function bindEventToChannel<EventName extends PusherEventName>(channel: string,
103
136
return ;
104
137
}
105
138
106
- let data : EventData < EventName > ;
107
- try {
108
- data = isObject ( eventData ) ? eventData : ( JSON . parse ( eventData ) as EventData < EventName > ) ;
109
- } catch ( err ) {
110
- Log . alert ( '[Pusher] Unable to parse single JSON event data from Pusher' , { error : err , eventData} ) ;
139
+ const data = parseEventData ( eventData ) ;
140
+ if ( ! data ) {
141
+ // Error already logged in parseEventData
111
142
return ;
112
143
}
113
144
if ( data . id === undefined || data . chunk === undefined || data . final === undefined ) {
0 commit comments