fix(discord): report pending message search indexes (#118573)

Co-authored-by: Peter Steinberger <steipete@macos.shared>
This commit is contained in:
Peter Steinberger
2026-08-03 02:13:42 -07:00
committed by GitHub
parent e797e69969
commit e97f484ef9
2 changed files with 48 additions and 1 deletions
@@ -66,6 +66,38 @@ describe("searchMessagesDiscord", () => {
expect(result).toEqual(results);
});
it("preserves valid empty Discord search results", async () => {
const results = { messages: [], total_results: 0 };
restMock.get.mockResolvedValueOnce(results);
await expect(
searchMessagesDiscord({ guildId: "G1", content: "test" }, { cfg: {} as never }),
).resolves.toEqual(results);
});
it("surfaces a pending Discord search index and its retry delay", async () => {
restMock.get.mockResolvedValueOnce({
message: "Index not yet available. Try again later",
code: 110000,
documents_indexed: 0,
retry_after: 2,
});
await expect(
searchMessagesDiscord({ guildId: "G1", content: "test" }, { cfg: {} as never }),
).rejects.toThrow(
"Discord message search unavailable: Index not yet available. Try again later (retry after 2s)",
);
});
it("rejects object search responses without a messages array", async () => {
restMock.get.mockResolvedValueOnce({ total_results: 1 });
await expect(
searchMessagesDiscord({ guildId: "G1", content: "test" }, { cfg: {} as never }),
).rejects.toThrow("Unexpected Discord response for message search: expected messages array.");
});
it("throws a clear error when Discord returns a non-object search response", async () => {
restMock.get.mockResolvedValueOnce("\u001f\ufffd\u0008raw gzip bytes");
+16 -1
View File
@@ -17,6 +17,7 @@ import {
searchGuildMessages,
unpinChannelMessage,
} from "./internal/discord.js";
import { parseDiscordRetryAfterBodySeconds } from "./retry-after.js";
import { resolveDiscordRest } from "./send.shared.js";
import type {
DiscordMessageEdit,
@@ -248,8 +249,22 @@ export async function searchMessagesDiscord(query: DiscordSearchQuery, opts: Dis
const limit = Math.min(Math.max(Math.floor(query.limit), 1), 25);
params.set("limit", String(limit));
}
return assertDiscordResponseObject(
const result = assertDiscordResponseObject(
await searchGuildMessages(rest, query.guildId, params),
"message search",
);
// Discord returns HTTP 202 with code 110000 while the guild search index is warming.
if (result.code === 110000) {
const message =
typeof result.message === "string" && result.message.trim()
? result.message.trim()
: "Discord search index is not yet available";
const retryAfter = parseDiscordRetryAfterBodySeconds(result.retry_after);
const retryHint = retryAfter === undefined ? "" : ` (retry after ${retryAfter}s)`;
throw new Error(`Discord message search unavailable: ${message}${retryHint}`);
}
if (!Array.isArray(result.messages)) {
throw new Error("Unexpected Discord response for message search: expected messages array.");
}
return result;
}