Updated activitypub Bluesky sharing enablement flow#23
Conversation
ref TryGhost/ActivityPub#1377 We updated the backend implementation of the Bluesky sharing enablement process to include a confirmation step in which the client would prompt the backend to check what handle has been assigned to the Bluesky account generated by Bridgy Fed - This circumvents the need to for us to compute the handle manually and potentially getting it wrong if we compute it in a different way to Bridgy Fed
Code Review by Qodo
1. tsconfig disables strict
|
|
|
||
| /* Linting */ | ||
| "strict": true, | ||
| "strict": false, |
There was a problem hiding this comment.
1. tsconfig disables strict 📘 Rule violation ✓ Correctness
• The TypeScript config sets compilerOptions.strict to false, weakening compile-time guarantees and allowing unsafe typing patterns. • This violates the requirement to enable strict typing (and, by extension, the associated noImplicitAny protections) for TypeScript configurations.
Agent prompt
## Issue description
`apps/activitypub/tsconfig.json` disables TypeScript strict mode, violating the requirement to keep `strict` (and `noImplicitAny`) enabled.
## Issue Context
The compliance checklist explicitly requires `compilerOptions.strict: true` and `compilerOptions.noImplicitAny: true`.
## Fix Focus Areas
- apps/activitypub/tsconfig.json[17-22]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| setIsEditingProfile(true); | ||
| } else { | ||
| setLoading(true); | ||
| try { | ||
| await enableBlueskyMutation.mutateAsync(); | ||
| toast.success('Bluesky sharing enabled'); | ||
| } finally { | ||
| setLoading(false); | ||
| } | ||
| await enableBlueskyMutation.mutateAsync(); | ||
| } | ||
| }; |
There was a problem hiding this comment.
2. handleenable lacks error handling 📘 Rule violation ⛯ Reliability
• handleEnable sets loading to true and awaits enableBlueskyMutation.mutateAsync() without any try/finally. • If the mutation rejects, loading may never be reset, leaving the UI stuck in a loading state and providing no actionable feedback to users.
Agent prompt
## Issue description
`handleEnable` sets `loading=true` and awaits `enableBlueskyMutation.mutateAsync()` without handling errors or resetting state on failure.
## Issue Context
If the mutation rejects, React state may never be reset, leaving the UI stuck and violating robust error handling requirements.
## Fix Focus Areas
- apps/activitypub/src/views/Preferences/components/BlueskySharing.tsx[48-55]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| const confirmHandle = useCallback(() => { | ||
| confirmBlueskyHandleMutation.mutateAsync().then((handle) => { | ||
| if (handle) { | ||
| setHandleConfirmed(true); | ||
| } | ||
| }); | ||
| // eslint-disable-next-line react-hooks/exhaustive-deps | ||
| }, []); // Empty deps - mutations are stable in practice | ||
|
|
||
| useEffect(() => { | ||
| if (!account?.blueskyEnabled) { | ||
| setHandleConfirmed(false); | ||
| setLoading(false); | ||
| retryCountRef.current = 0; | ||
|
|
||
| return; | ||
| } | ||
|
|
||
| if (account?.blueskyHandleConfirmed) { | ||
| setHandleConfirmed(true); | ||
| setLoading(false); | ||
|
|
||
| // Only show toast on first confirmation | ||
| if (retryCountRef.current > 0) { | ||
| toast.success('Bluesky sharing enabled'); | ||
| } | ||
| retryCountRef.current = 0; | ||
|
|
||
| return; | ||
| } | ||
|
|
||
| setHandleConfirmed(false); | ||
| setLoading(true); | ||
| retryCountRef.current = 0; | ||
|
|
||
| const confirmHandleInterval = setInterval(async () => { | ||
| if (retryCountRef.current >= MAX_CONFIRMATION_RETRIES) { | ||
| clearInterval(confirmHandleInterval); | ||
|
|
||
| toast.error('Something went wrong, please try again.'); | ||
|
|
||
| await disableBlueskyMutation.mutateAsync(); | ||
| setLoading(false); | ||
|
|
||
| return; | ||
| } | ||
|
|
||
| retryCountRef.current += 1; | ||
| confirmHandle(); | ||
| }, CONFIRMATION_INTERVAL); |
There was a problem hiding this comment.
4. Polling overlaps & unhandled rejections 🐞 Bug ⛯ Reliability
• The confirmation loop uses setInterval but does not await the confirmation request, so a slow request can overlap with the next tick and create concurrent confirm calls. • confirmHandle attaches only .then(...) to mutateAsync() with no .catch(...); any rejection becomes an unhandled promise rejection (especially likely when called repeatedly by a timer). • The interval callback also awaits disableBlueskyMutation.mutateAsync() on timeout with no try/catch, which can also reject and leak an unhandled promise.
Agent prompt
### Issue description
The new confirmation polling uses a timer to trigger async work without awaiting completion and without catching rejections. This can cause overlapping confirmation requests and unhandled promise rejections.
### Issue Context
The API layer throws on non-2xx responses, so `mutateAsync()` can reject. Timer-driven code must always handle rejections.
### Fix Focus Areas
- apps/activitypub/src/views/Preferences/components/BlueskySharing.tsx[68-121]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Benchmark PR from qodo-benchmark#244