refactor: normalize about output + retry helper
This commit is contained in:
@@ -49,6 +49,18 @@ export abstract class TwitterClientBase {
|
||||
}
|
||||
}
|
||||
|
||||
protected async withRefreshedQueryIdsOn404<T extends { success: boolean; had404?: boolean }>(
|
||||
attempt: () => Promise<T>,
|
||||
): Promise<{ result: T; refreshed: boolean }> {
|
||||
const firstAttempt = await attempt();
|
||||
if (firstAttempt.success || !firstAttempt.had404) {
|
||||
return { result: firstAttempt, refreshed: false };
|
||||
}
|
||||
await this.refreshQueryIds();
|
||||
const secondAttempt = await attempt();
|
||||
return { result: secondAttempt, refreshed: true };
|
||||
}
|
||||
|
||||
protected async getTweetDetailQueryIds(): Promise<string[]> {
|
||||
const primary = await this.getQueryId('TweetDetail');
|
||||
return Array.from(new Set([primary, '97JF30KziU00483E_8elBA', 'aFvUsJm2c-oDkJV75blV6g']));
|
||||
|
||||
@@ -307,21 +307,11 @@ export function withUserLookup<TBase extends AbstractConstructor<TwitterClientBa
|
||||
};
|
||||
};
|
||||
|
||||
const firstAttempt = await tryOnce();
|
||||
if (firstAttempt.success) {
|
||||
return { success: true, aboutProfile: firstAttempt.aboutProfile };
|
||||
const { result } = await this.withRefreshedQueryIdsOn404(tryOnce);
|
||||
if (result.success) {
|
||||
return { success: true, aboutProfile: result.aboutProfile };
|
||||
}
|
||||
|
||||
if (firstAttempt.had404) {
|
||||
await this.refreshQueryIds();
|
||||
const secondAttempt = await tryOnce();
|
||||
if (secondAttempt.success) {
|
||||
return { success: true, aboutProfile: secondAttempt.aboutProfile };
|
||||
}
|
||||
return { success: false, error: secondAttempt.error };
|
||||
}
|
||||
|
||||
return { success: false, error: firstAttempt.error };
|
||||
return { success: false, error: result.error };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -331,29 +331,21 @@ export function withUsers<TBase extends AbstractConstructor<TwitterClientBase>>(
|
||||
return { success: false as const, error: lastError ?? 'Unknown error fetching following', had404 };
|
||||
};
|
||||
|
||||
const firstAttempt = await tryOnce();
|
||||
if (firstAttempt.success) {
|
||||
return { success: true, users: firstAttempt.users, nextCursor: firstAttempt.nextCursor };
|
||||
const { result, refreshed } = await this.withRefreshedQueryIdsOn404(tryOnce);
|
||||
if (result.success) {
|
||||
return { success: true, users: result.users, nextCursor: result.nextCursor };
|
||||
}
|
||||
|
||||
if (firstAttempt.had404) {
|
||||
await this.refreshQueryIds();
|
||||
const secondAttempt = await tryOnce();
|
||||
if (secondAttempt.success) {
|
||||
return { success: true, users: secondAttempt.users, nextCursor: secondAttempt.nextCursor };
|
||||
}
|
||||
|
||||
if (refreshed) {
|
||||
// GraphQL Following can also return 404 (queryId churn / endpoint flakiness).
|
||||
// Fallback to the internal v1.1 REST endpoint used by the web client through the relay.
|
||||
const restAttempt = await this.getFollowingViaRest(userId, count, cursor);
|
||||
if (restAttempt.success) {
|
||||
return restAttempt;
|
||||
}
|
||||
|
||||
return { success: false, error: secondAttempt.error };
|
||||
}
|
||||
|
||||
return { success: false, error: firstAttempt.error };
|
||||
return { success: false, error: result.error };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -436,29 +428,21 @@ export function withUsers<TBase extends AbstractConstructor<TwitterClientBase>>(
|
||||
return { success: false as const, error: lastError ?? 'Unknown error fetching followers', had404 };
|
||||
};
|
||||
|
||||
const firstAttempt = await tryOnce();
|
||||
if (firstAttempt.success) {
|
||||
return { success: true, users: firstAttempt.users, nextCursor: firstAttempt.nextCursor };
|
||||
const { result, refreshed } = await this.withRefreshedQueryIdsOn404(tryOnce);
|
||||
if (result.success) {
|
||||
return { success: true, users: result.users, nextCursor: result.nextCursor };
|
||||
}
|
||||
|
||||
if (firstAttempt.had404) {
|
||||
await this.refreshQueryIds();
|
||||
const secondAttempt = await tryOnce();
|
||||
if (secondAttempt.success) {
|
||||
return { success: true, users: secondAttempt.users, nextCursor: secondAttempt.nextCursor };
|
||||
}
|
||||
|
||||
if (refreshed) {
|
||||
// GraphQL Followers regularly returns 404 (queryId churn / endpoint flakiness).
|
||||
// Fallback to the internal v1.1 REST endpoint used by the web client through the relay.
|
||||
const restAttempt = await this.getFollowersViaRest(userId, count, cursor);
|
||||
if (restAttempt.success) {
|
||||
return restAttempt;
|
||||
}
|
||||
|
||||
return { success: false, error: secondAttempt.error };
|
||||
}
|
||||
|
||||
return { success: false, error: firstAttempt.error };
|
||||
return { success: false, error: result.error };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user