-
Notifications
You must be signed in to change notification settings - Fork 0
🧹 Refactor fetchActivity to use native Promise.allSettled
#374
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -682,21 +682,23 @@ export const fetchActivity = cache(async function fetchActivity( | |
| ) | ||
| ); | ||
|
|
||
| // Suppress unhandled promise rejections for subsequent pages if we break early or throw | ||
| promises.forEach((p) => p.catch((e) => logger.error("Event fetch promise rejected:", e))); | ||
| // Use allSettled to natively handle all promises and avoid unhandled rejections | ||
| const results = await Promise.allSettled(promises); | ||
|
|
||
| for (const p of promises) { | ||
| try { | ||
| const events = await p; | ||
| for (const result of results) { | ||
| if (result.status === "fulfilled") { | ||
| const events = result.value; | ||
| allEvents.push(...events); | ||
| if (events.length < 100) break; | ||
| } catch (error) { | ||
| } else { | ||
| const error = result.reason; | ||
| if ( | ||
| error instanceof UserNotFoundError || | ||
| error instanceof RateLimitError | ||
| ) { | ||
| throw error; | ||
| } | ||
| logger.error("Event fetch promise rejected:", error); | ||
| break; | ||
| } | ||
|
Comment on lines
+688
to
703
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 変更前は 変更後は Prompt To Fix With AIThis is a comment left during a code review.
Path: src/lib/github.ts
Line: 688-703
Comment:
**ログ出力の動作変更**
変更前は `.forEach(p => p.catch((e) => logger.error(...)))` が全 3 Promise すべてにキャッチハンドラを登録していたため、どの Promise が reject しても必ずログに記録されていました。
変更後は `for...of` ループ内で最初の rejected 結果を `logger.error` してから `break` するため、2 番目・3 番目の reject はサイレントに吸収されます。たとえばページ 1 が non-critical error で `break` した後、ページ 2・3 も別の理由で失敗していた場合にそれらがログに残りません。
How can I resolve this? If you propose a fix, please make it concise. |
||
| } | ||
|
Comment on lines
+685
to
704
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using In the original implementation, if the first page returned fewer than 100 events, the loop would To preserve the early-exit latency optimization while safely handling unhandled promise rejections, it is better to stick to the original pattern of attaching a // Suppress unhandled promise rejections for subsequent pages if we break early or throw
promises.forEach((p) => p.catch((e) => logger.error("Event fetch promise rejected:", e)));
for (const p of promises) {
try {
const events = await p;
allEvents.push(...events);
if (events.length < 100) break;
} catch (error) {
if (
error instanceof UserNotFoundError ||
error instanceof RateLimitError
) {
throw error;
}
break;
}
}References
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
変更前は
for...ofループで各 Promise を逐次awaitしていたため、ページ 1 のレスポンスが < 100 件だった時点で即座にbreak・返却できていました(ページ 2・3 はリクエスト自体は飛んでいたが、関数の返却はt_page1だった)。変更後は
Promise.allSettled(promises)が全 3 つの Promise が settle するまで待機するため、ページ 1 が < 100 件またはUserNotFoundErrorで失敗した場合でもmax(t_page1, t_page2, t_page3)待ってから初めてループ処理に入ります。イベント数が少ないユーザー(最も一般的なケース)で毎回余分な待ち時間が生じます。PR 説明の「same functional behavior including early exits」という主張とも整合しません。Prompt To Fix With AI
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!