From 7acb17efd8c260c5d52840dc6c3b99eade2dd488 Mon Sep 17 00:00:00 2001 From: Shreyas2004wagh Date: Wed, 11 Feb 2026 20:44:48 +0530 Subject: [PATCH 1/2] fix(api): remove typing busy-wait and harden API handling --- packages/api/src/EmbeddedChatApi.ts | 113 +++++++++++++++------------- 1 file changed, 59 insertions(+), 54 deletions(-) diff --git a/packages/api/src/EmbeddedChatApi.ts b/packages/api/src/EmbeddedChatApi.ts index 72e25a046..30912192d 100644 --- a/packages/api/src/EmbeddedChatApi.ts +++ b/packages/api/src/EmbeddedChatApi.ts @@ -7,8 +7,6 @@ import { ApiError, } from "@embeddedchat/auth"; -// mutliple typing status can come at the same time they should be processed in order. -let typingHandlerLock = 0; export default class EmbeddedChatApi { host: string; rid: string; @@ -60,6 +58,13 @@ export default class EmbeddedChatApi { return this.host; } + private throwApiError(error: unknown): never { + if (error instanceof Error || error instanceof ApiError) { + throw error; + } + throw new Error(String(error)); + } + /** * Todo refactor */ @@ -113,7 +118,7 @@ export default class EmbeddedChatApi { return response; } } catch (err) { - console.error(err); + this.throwApiError(err); } } @@ -142,7 +147,7 @@ export default class EmbeddedChatApi { const authErrorRes = await error.response.json(); return { error: authErrorRes?.error }; } - console.error(error); + this.throwApiError(error); } } @@ -169,7 +174,7 @@ export default class EmbeddedChatApi { break; } } catch (error) { - console.error("Auto-login failed:", error); + this.throwApiError(error); } } @@ -177,7 +182,7 @@ export default class EmbeddedChatApi { try { await this.auth.logout(); } catch (err) { - console.error(err); + this.throwApiError(err); } } @@ -196,7 +201,7 @@ export default class EmbeddedChatApi { if (!data) { return; } - const message = JSON.parse(JSON.stringify(data)); + const message = { ...data }; if (message.ts?.$date) { console.log(message.ts?.$date); message.ts = message.ts.$date; @@ -253,7 +258,7 @@ export default class EmbeddedChatApi { if (!data || data?.rid !== this.rid) { return; } - const message = JSON.parse(JSON.stringify(data)); + const message = { ...data }; if (message.ts?.$date) { message.ts = message.ts.$date; } @@ -270,7 +275,12 @@ export default class EmbeddedChatApi { } ); } catch (err) { - await this.close(); + try { + await this.close(); + } catch { + // Preserve the original error from connect flow. + } + this.throwApiError(err); } } @@ -358,13 +368,6 @@ export default class EmbeddedChatApi { typingUser: string; isTyping: boolean; }) { - // don't wait for more than 2 seconds. Though in practical, the waiting time is insignificant. - setTimeout(() => { - typingHandlerLock = 0; - }, 2000); - // eslint-disable-next-line no-empty - while (typingHandlerLock) {} - typingHandlerLock = 1; // move user to front if typing else remove it. const idx = this.typingUsers.indexOf(typingUser); if (idx !== -1) { @@ -373,7 +376,6 @@ export default class EmbeddedChatApi { if (isTyping) { this.typingUsers.unshift(typingUser); } - typingHandlerLock = 0; const newTypingStatus = cloneArray(this.typingUsers); this.onTypingStatusCallbacks.forEach((callback) => callback(newTypingStatus) @@ -391,7 +393,7 @@ export default class EmbeddedChatApi { } return await response.json(); } catch (err) { - console.error(err); + this.throwApiError(err); } } @@ -429,7 +431,7 @@ export default class EmbeddedChatApi { return await response2.json(); } } catch (error) { - console.error(error); + this.throwApiError(error); } } @@ -464,7 +466,7 @@ export default class EmbeddedChatApi { } return result; } catch (err) { - console.error(err); + this.throwApiError(err); } } else { return this.updateUserNameThroughSuggestion(userid); @@ -487,7 +489,7 @@ export default class EmbeddedChatApi { ); return await response.json(); } catch (err) { - console.error(err); + this.throwApiError(err); } } @@ -522,7 +524,7 @@ export default class EmbeddedChatApi { } return null; } catch (err) { - console.error(err); + this.throwApiError(err); } } @@ -539,7 +541,7 @@ export default class EmbeddedChatApi { }); return await response.json(); } catch (err) { - console.error(err); + this.throwApiError(err); } } @@ -589,7 +591,7 @@ export default class EmbeddedChatApi { ); return await messages.json(); } catch (err) { - console.log(err); + this.throwApiError(err); } } @@ -630,7 +632,7 @@ export default class EmbeddedChatApi { ); return await messages.json(); } catch (err) { - console.log(err); + this.throwApiError(err); } } @@ -650,7 +652,7 @@ export default class EmbeddedChatApi { ); return await messages.json(); } catch (err) { - console.log(err); + this.throwApiError(err); } } @@ -671,7 +673,7 @@ export default class EmbeddedChatApi { ); return await roles.json(); } catch (err) { - console.log(err); + this.throwApiError(err); } } @@ -691,7 +693,7 @@ export default class EmbeddedChatApi { ); return await roles.json(); } catch (err) { - console.log(err); + this.throwApiError(err); } } @@ -726,7 +728,7 @@ export default class EmbeddedChatApi { } return null; } catch (err) { - console.error(err); + this.throwApiError(err); } } @@ -739,7 +741,7 @@ export default class EmbeddedChatApi { typing ? ["user-typing"] : [] ); } catch (err) { - console.error(err); + this.throwApiError(err); } } @@ -774,7 +776,7 @@ export default class EmbeddedChatApi { }); return await response.json(); } catch (err) { - console.error(err); + this.throwApiError(err); } } @@ -792,7 +794,7 @@ export default class EmbeddedChatApi { }); return await response.json(); } catch (err) { - console.error(err); + this.throwApiError(err); } } @@ -810,7 +812,7 @@ export default class EmbeddedChatApi { }); return await response.json(); } catch (err) { - console.error(err); + this.throwApiError(err); } } @@ -832,7 +834,7 @@ export default class EmbeddedChatApi { }); return await response.json(); } catch (err) { - console.error(err); + this.throwApiError(err); } } @@ -852,7 +854,7 @@ export default class EmbeddedChatApi { ); return await response.json(); } catch (err) { - console.error(err); + this.throwApiError(err); } } @@ -870,7 +872,7 @@ export default class EmbeddedChatApi { }); return await response.json(); } catch (err) { - console.error(err); + this.throwApiError(err); } } @@ -888,7 +890,7 @@ export default class EmbeddedChatApi { }); return await response.json(); } catch (err) { - console.error(err); + this.throwApiError(err); } } @@ -908,7 +910,7 @@ export default class EmbeddedChatApi { ); return await response.json(); } catch (err) { - console.error(err); + this.throwApiError(err); } } @@ -928,7 +930,7 @@ export default class EmbeddedChatApi { ); return await response.json(); } catch (err) { - console.error(err); + this.throwApiError(err); } } @@ -948,7 +950,7 @@ export default class EmbeddedChatApi { ); return await response.json(); } catch (err) { - console.error(err); + this.throwApiError(err); } } @@ -966,9 +968,7 @@ export default class EmbeddedChatApi { }); return await response.json(); } catch (err) { - return { - error: err, - }; + this.throwApiError(err); } } @@ -986,7 +986,7 @@ export default class EmbeddedChatApi { }); return await response.json(); } catch (err) { - console.error(err); + this.throwApiError(err); } } @@ -1008,7 +1008,7 @@ export default class EmbeddedChatApi { }); return await response.json(); } catch (err) { - console.error(err); + this.throwApiError(err); } } @@ -1026,7 +1026,7 @@ export default class EmbeddedChatApi { }); return await response.json(); } catch (err) { - console.error(err); + this.throwApiError(err); } } @@ -1044,7 +1044,7 @@ export default class EmbeddedChatApi { }); return await response.json(); } catch (err) { - console.log(err); + this.throwApiError(err); } } @@ -1075,7 +1075,7 @@ export default class EmbeddedChatApi { }).then((r) => r.json()); return response; } catch (err) { - console.log(err); + this.throwApiError(err); } } @@ -1092,7 +1092,7 @@ export default class EmbeddedChatApi { }); return await response.json(); } catch (err) { - console.error(err); + this.throwApiError(err); } } @@ -1113,15 +1113,19 @@ export default class EmbeddedChatApi { ); return await response.json(); } catch (err) { - console.error(err); + this.throwApiError(err); } } async getSearchMessages(text: string) { try { const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; + const queryParams = new URLSearchParams({ + roomId: this.rid, + searchText: text, + }); const response = await fetch( - `${this.host}/api/v1/chat.search?roomId=${this.rid}&searchText=${text}`, + `${this.host}/api/v1/chat.search?${queryParams.toString()}`, { headers: { "Content-Type": "application/json", @@ -1133,7 +1137,7 @@ export default class EmbeddedChatApi { ); return await response.json(); } catch (err) { - console.error(err); + this.throwApiError(err); } } @@ -1153,7 +1157,7 @@ export default class EmbeddedChatApi { ); return await response.json(); } catch (err) { - console.error(err); + this.throwApiError(err); } } @@ -1183,7 +1187,7 @@ export default class EmbeddedChatApi { this.onActionTriggeredCallbacks.forEach((cb) => cb(interaction)); return interaction; } catch (e) { - console.error(e); + this.throwApiError(e); } } @@ -1281,3 +1285,4 @@ export default class EmbeddedChatApi { return data; } } + From 1bac2c45f888a84bd406c95043b358bdcd60ef50 Mon Sep 17 00:00:00 2001 From: Shreyas2004wagh Date: Wed, 11 Feb 2026 21:00:11 +0530 Subject: [PATCH 2/2] fix(api): address PR review feedback for error helper and pinMessage --- packages/api/src/EmbeddedChatApi.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/api/src/EmbeddedChatApi.ts b/packages/api/src/EmbeddedChatApi.ts index 30912192d..c01fe96f5 100644 --- a/packages/api/src/EmbeddedChatApi.ts +++ b/packages/api/src/EmbeddedChatApi.ts @@ -59,7 +59,7 @@ export default class EmbeddedChatApi { } private throwApiError(error: unknown): never { - if (error instanceof Error || error instanceof ApiError) { + if (error instanceof Error) { throw error; } throw new Error(String(error)); @@ -203,7 +203,6 @@ export default class EmbeddedChatApi { } const message = { ...data }; if (message.ts?.$date) { - console.log(message.ts?.$date); message.ts = message.ts.$date; } if (!message.ts) { @@ -968,7 +967,9 @@ export default class EmbeddedChatApi { }); return await response.json(); } catch (err) { - this.throwApiError(err); + return { + error: err, + }; } } @@ -1285,4 +1286,3 @@ export default class EmbeddedChatApi { return data; } } -