Handle Graph API conversation fetch failures without stalling UI (ERMAIN-347)#769
Draft
bdart wants to merge 4 commits into
Draft
Handle Graph API conversation fetch failures without stalling UI (ERMAIN-347)#769bdart wants to merge 4 commits into
bdart wants to merge 4 commits into
Conversation
When the Graph API conversation fetch is slow or times out (up to 20s), the chat-input composer was disabled for the entire fetch duration via isWaitingForSuggestedEmail. This freezes the UI for users on slow or flaky networks. Changes: - Add OUTLOOK_GRAPH_THREAD_UI_BLOCK_DEADLINE_MS (5s) to graphRequestTimeout.ts - Add isBlockingLoad to UseCurrentThreadResult: true while the fetch is in-flight AND within the short deadline; false once the deadline elapses (even if the fetch is still running) or when the fetch completes/errors - Expose isBlockingLoadEmailBody from OutlookEmailSourceProvider, mapping directly from useCurrentThread.isBlockingLoad - Update AddinChatInput.isWaitingForSuggestedEmail to gate on isBlockingLoadEmailBody instead of isLoadingEmailBody The loading chip (driven by isLoadingEmailBody) continues to display for the full fetch duration so the user knows the email context is still resolving. If the fetch eventually succeeds the email is attached when the user sends. The UI is never blocked for more than 5 seconds. Co-authored-by: Daniel <bdart@users.noreply.github.com>
Add tests for: - isBlockingLoad is false when fetch is disabled - isBlockingLoad is true during initial load, flips false after deadline - isBlockingLoad is false immediately on fetch error - isBlockingLoad resets to true on conversationId change after deadline - isBlockingLoadEmailBody is forwarded from useCurrentThread via provider Update existing toEqual assertions to include the new isBlockingLoad field. Co-authored-by: Daniel <bdart@users.noreply.github.com>
Reflects the freshly-built frontend library tarball produced during dependency installation for the test run. Co-authored-by: Daniel <bdart@users.noreply.github.com>
- Run prettier on useCurrentThread.ts and useCurrentThread.test.ts - Remove the eslint-disable-line react-hooks/exhaustive-deps comment; the rule does not flag the deps array since OUTLOOK_GRAPH_THREAD_UI_BLOCK_DEADLINE_MS is a module-level constant and setIsWithinBlockDeadline is a stable state setter — both are correctly excluded by the rule Co-authored-by: Daniel <bdart@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When the Graph API conversation fetch is slow or times out (full timeout is 20 seconds), the chat-input composer was disabled for the entire wait via
isWaitingForSuggestedEmail. Users on slow or flaky networks were unable to type for up to 20 seconds — the UI appeared frozen.The email loading chip was already shown, providing a visual indicator, but the send button remained disabled for the full fetch duration.
Solution
Introduce a short UI-block deadline (5 seconds). The composer blocks briefly — enough for a fast network to return the email context and attach it automatically — then unblocks after the deadline regardless of whether the fetch has completed.
The loading chip continues to display for the full fetch duration so the user knows the email context is still resolving. If the fetch eventually succeeds before the user sends, the email is still included.
Changes
office-addin/src/utils/graphRequestTimeout.tsOUTLOOK_GRAPH_THREAD_UI_BLOCK_DEADLINE_MS = 5_000with a clear docstring explaining the intent.office-addin/src/hooks/useCurrentThread.tsisBlockingLoad: booleantoUseCurrentThreadResult.truewhile the fetch is in-flight and within the 5-second deadline.falseonce the deadline elapses (even if the fetch is still running), or when the fetch completes or errors.itemId/conversationIdchanges, so switching conversations re-blocks the input briefly for the new fetch.office-addin/src/providers/OutlookEmailSourceProvider.tsxisBlockingLoadEmailBody: booleantoOutlookEmailSourceContextValue, mapped fromuseCurrentThread.isBlockingLoad.isLoadingEmailBodyunchanged — it still drives the loading chip for the full fetch duration.office-addin/src/components/AddinChatInput.tsxisWaitingForSuggestedEmailto gate onisBlockingLoadEmailBody(5-second window) instead ofisLoadingEmailBody(full fetch duration).shouldShowEmailSourcePreviewand the chip rendering logic continue to useisLoadingEmailBodyso the loading chip remains visible throughout.Tests
useCurrentThread.test.ts: 4 new cases forisBlockingLoad:conversationIdchanges after the deadline elapsedOutlookEmailSourceProvider.test.tsx: 2 new cases verifyingisBlockingLoadEmailBodyis forwarded correctly fromuseCurrentThread, including the "deadline elapsed but still loading" scenario.toEqualassertions inuseCurrentThread.test.tsto includeisBlockingLoad: false.All 524 tests pass.
Linear Issue: ERMAIN-347