fix(#298): Fix async response handling in dashboard
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Replaced setTimeout hacks with proper polling mechanism: - Added pollForQueryResponse() function with configurable polling interval - Polls every 500ms with 30s timeout - Properly handles DELIVERED and FAILED message states - Throws errors for failures and timeouts Updated dashboard to use polling instead of arbitrary delays: - Removed setTimeout(resolve, 1000) hacks - Added proper async/await for query responses - Improved response data parsing for new query format - Better error handling via polling exceptions This fixes race conditions and unreliable data loading. Fixes #298 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -88,3 +88,45 @@ export async function fetchQueryMessages(
|
||||
export async function fetchQueryMessage(messageId: string): Promise<QueryMessageDetails> {
|
||||
return apiGet<QueryMessageDetails>(`/api/v1/federation/queries/${messageId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Poll for query response with timeout
|
||||
* @param messageId - The message ID to poll for
|
||||
* @param options - Polling options
|
||||
* @returns The query message details when delivered or failed
|
||||
* @throws Error if timeout is reached or message fails
|
||||
*/
|
||||
export async function pollForQueryResponse(
|
||||
messageId: string,
|
||||
options?: {
|
||||
pollInterval?: number; // milliseconds between polls (default: 500)
|
||||
timeout?: number; // maximum time to wait in milliseconds (default: 30000)
|
||||
}
|
||||
): Promise<QueryMessageDetails> {
|
||||
const pollInterval = options?.pollInterval ?? 500;
|
||||
const timeout = options?.timeout ?? 30000;
|
||||
const startTime = Date.now();
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
while (true) {
|
||||
// Check if timeout has been reached
|
||||
if (Date.now() - startTime > timeout) {
|
||||
throw new Error(`Query timeout after ${String(timeout)}ms`);
|
||||
}
|
||||
|
||||
// Fetch the message
|
||||
const message = await fetchQueryMessage(messageId);
|
||||
|
||||
// Check if the message is complete
|
||||
if (message.status === FederationMessageStatus.DELIVERED) {
|
||||
return message;
|
||||
}
|
||||
|
||||
if (message.status === FederationMessageStatus.FAILED) {
|
||||
throw new Error(message.error ?? "Query failed");
|
||||
}
|
||||
|
||||
// Wait before polling again
|
||||
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user