From aa55ba1332dfeebeeba3e78dd1b2f11fdf873d93 Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Tue, 2 Jun 2026 10:01:04 -0400 Subject: [PATCH] fix: suppress unhandled promise rejections from fire-and-forget useEffect loads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit useAsync re-throws errors after storing them in state — correct for awaited callers but causes unhandled rejections when load() is called without .catch() in useEffects. The error is already captured in AsyncState.Error so the re-throw provides no additional value in these fire-and-forget patterns. Fixes JAVASCRIPT-REACT-M (Sentry: Media download failed: 401 Unauthorized) Co-Authored-By: Claude Sonnet 4.6 --- src/app/components/ClientConfigLoader.tsx | 2 +- src/app/components/message/content/ImageContent.tsx | 2 +- src/app/components/message/content/ThumbnailContent.tsx | 2 +- src/app/components/message/content/VideoContent.tsx | 2 +- src/app/features/room/message/EditHistoryModal.tsx | 2 +- src/app/hooks/useAsyncCallback.ts | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/app/components/ClientConfigLoader.tsx b/src/app/components/ClientConfigLoader.tsx index 72d367c06..769b9f2c7 100644 --- a/src/app/components/ClientConfigLoader.tsx +++ b/src/app/components/ClientConfigLoader.tsx @@ -21,7 +21,7 @@ export function ClientConfigLoader({ fallback, error, children }: ClientConfigLo const ignoreCallback = useCallback(() => setIgnoreError(true), []); useEffect(() => { - load(); + void load().catch(() => undefined); }, [load]); if (state.status === AsyncStatus.Idle || state.status === AsyncStatus.Loading) { diff --git a/src/app/components/message/content/ImageContent.tsx b/src/app/components/message/content/ImageContent.tsx index d9848e47d..0b25aca23 100644 --- a/src/app/components/message/content/ImageContent.tsx +++ b/src/app/components/message/content/ImageContent.tsx @@ -113,7 +113,7 @@ export const ImageContent = as<'div', ImageContentProps>( }; useEffect(() => { - if (autoPlay) loadSrc(); + if (autoPlay) void loadSrc().catch(() => undefined); }, [autoPlay, loadSrc]); return ( diff --git a/src/app/components/message/content/ThumbnailContent.tsx b/src/app/components/message/content/ThumbnailContent.tsx index 099c934a8..984e3f68b 100644 --- a/src/app/components/message/content/ThumbnailContent.tsx +++ b/src/app/components/message/content/ThumbnailContent.tsx @@ -37,7 +37,7 @@ export function ThumbnailContent({ info, renderImage }: ThumbnailContentProps) { ); useEffect(() => { - loadThumbSrc(); + void loadThumbSrc().catch(() => undefined); }, [loadThumbSrc]); return thumbSrcState.status === AsyncStatus.Success ? renderImage(thumbSrcState.data) : null; diff --git a/src/app/components/message/content/VideoContent.tsx b/src/app/components/message/content/VideoContent.tsx index 7dc78fa8e..91c6efc68 100644 --- a/src/app/components/message/content/VideoContent.tsx +++ b/src/app/components/message/content/VideoContent.tsx @@ -106,7 +106,7 @@ export const VideoContent = as<'div', VideoContentProps>( }; useEffect(() => { - if (autoPlay) loadSrc(); + if (autoPlay) void loadSrc().catch(() => undefined); }, [autoPlay, loadSrc]); return ( diff --git a/src/app/features/room/message/EditHistoryModal.tsx b/src/app/features/room/message/EditHistoryModal.tsx index ce7661fba..9a00493de 100644 --- a/src/app/features/room/message/EditHistoryModal.tsx +++ b/src/app/features/room/message/EditHistoryModal.tsx @@ -106,7 +106,7 @@ export function EditHistoryModal({ room, mEvent, onClose }: EditHistoryModalProp ); useEffect(() => { - fetchHistory(); + void fetchHistory().catch(() => undefined); }, [fetchHistory]); const formatTs = (ts: number): string => { diff --git a/src/app/hooks/useAsyncCallback.ts b/src/app/hooks/useAsyncCallback.ts index f3b0eb26c..11d812ebe 100644 --- a/src/app/hooks/useAsyncCallback.ts +++ b/src/app/hooks/useAsyncCallback.ts @@ -114,7 +114,7 @@ export const useAsyncCallbackValue = ( const [state, load] = useAsyncCallback(asyncCallback); useEffect(() => { - load(); + void load().catch(() => undefined); }, [load]); return [state, load];