Skip to content

Commit 93a51cf

Browse files
sij411claude
andcommitted
Address review feedback on smoke test harness
- Fix scheme mismatch in fallback actor URI construction: actorId now uses the same scheme variable as inboxId instead of hardcoding https:// - Replace try/catch with empty catch blocks in lookupFedifyAccount() with direct fetch + res.ok checks, letting real network errors propagate naturally - Add 10-second fetch timeout to WebFinger and actor document resolution to prevent indefinite hangs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 458220e commit 93a51cf

File tree

2 files changed

+31
-31
lines changed

2 files changed

+31
-31
lines changed

test/smoke/harness/backdoor.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ function json(data: unknown, status = 200): Response {
1212
// Resolve a handle (user@domain) to the correct actor URI and inbox URL
1313
// via WebFinger + actor document fetch. Falls back to the Mastodon URL
1414
// convention (/users/{username}) when WebFinger is unavailable.
15+
const FETCH_TIMEOUT_MS = 10_000;
1516
const recipientCache = new Map<string, { inboxId: URL; actorId: URL }>();
1617

1718
async function parseRecipient(
@@ -31,6 +32,7 @@ async function parseRecipient(
3132
}`;
3233
const wfRes = await fetch(wfUrl, {
3334
headers: { Accept: "application/jrd+json" },
35+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
3436
});
3537
if (wfRes.ok) {
3638
const wf = await wfRes.json() as {
@@ -44,6 +46,7 @@ async function parseRecipient(
4446
// Fetch the actor document to discover the inbox URL
4547
const actorRes = await fetch(self.href, {
4648
headers: { Accept: "application/activity+json" },
49+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
4750
});
4851
if (actorRes.ok) {
4952
const actor = await actorRes.json() as { inbox?: string };
@@ -61,7 +64,7 @@ async function parseRecipient(
6164

6265
// Fallback: construct URLs using Mastodon convention
6366
const inboxId = new URL(`${scheme}://${domain}/users/${user}/inbox`);
64-
const actorId = new URL(`https://${domain}/users/${user}`);
67+
const actorId = new URL(`${scheme}://${domain}/users/${user}`);
6568
const result = { inboxId, actorId };
6669
recipientCache.set(handle, result);
6770
return result;

test/smoke/orchestrator.ts

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -156,50 +156,47 @@ async function lookupFedifyAccount(): Promise<string> {
156156
const handle = `testuser@${HARNESS_HOST}`;
157157

158158
const searchResult = await poll("Fedify user resolvable", async () => {
159+
const authHeaders = { Authorization: `Bearer ${SERVER_TOKEN}` };
160+
159161
// Try /api/v1/accounts/search (Mastodon standard).
160-
// Fall back to /api/v1/accounts/lookup (exact match, supported by Sharkey)
161-
// if search returns 404.
162-
try {
163-
const results = await serverGet(
164-
`/api/v1/accounts/search?q=${
165-
encodeURIComponent(`@${handle}`)
166-
}&resolve=true&limit=5`,
167-
) as RemoteAccount[];
162+
const searchRes = await fetch(
163+
`${SERVER_URL}/api/v1/accounts/search?q=${
164+
encodeURIComponent(`@${handle}`)
165+
}&resolve=true&limit=5`,
166+
{ headers: authHeaders },
167+
);
168+
if (searchRes.ok) {
169+
const results = await searchRes.json() as RemoteAccount[];
168170
const match = results?.find((a) =>
169171
a.acct === handle || a.acct === `@${handle}`
170172
);
171173
if (match) return match;
172-
} catch {
173-
// Search endpoint may return 404 on some servers (e.g. Sharkey);
174-
// fall through to the lookup endpoint.
175174
}
176175

177-
try {
178-
const account = await serverGet(
179-
`/api/v1/accounts/lookup?acct=${encodeURIComponent(handle)}`,
180-
) as RemoteAccount;
176+
// Fall back to /api/v1/accounts/lookup (exact match, supported by
177+
// Sharkey) if search didn't return a match.
178+
const lookupRes = await fetch(
179+
`${SERVER_URL}/api/v1/accounts/lookup?acct=${encodeURIComponent(handle)}`,
180+
{ headers: authHeaders },
181+
);
182+
if (lookupRes.ok) {
183+
const account = await lookupRes.json() as RemoteAccount;
181184
if (account?.id) return account;
182-
} catch {
183-
// lookup also failed
184185
}
185186

186187
// Misskey-native fallback: POST /api/users/show with username + host.
187188
// Sharkey's Mastodon-compat search/lookup endpoints have bugs with
188189
// remote users, but the native API works reliably. The returned id
189190
// is the same internal ID used by the Mastodon-compat layer.
190-
try {
191-
const [user, host] = handle.split("@");
192-
const res = await fetch(`${SERVER_URL}/api/users/show`, {
193-
method: "POST",
194-
headers: { "Content-Type": "application/json" },
195-
body: JSON.stringify({ username: user, host }),
196-
});
197-
if (res.ok) {
198-
const data = await res.json() as { id?: string };
199-
if (data?.id) return { id: data.id, acct: handle };
200-
}
201-
} catch {
202-
// Not a Misskey-family server
191+
const [user, host] = handle.split("@");
192+
const misskeyRes = await fetch(`${SERVER_URL}/api/users/show`, {
193+
method: "POST",
194+
headers: { "Content-Type": "application/json" },
195+
body: JSON.stringify({ username: user, host }),
196+
});
197+
if (misskeyRes.ok) {
198+
const data = await misskeyRes.json() as { id?: string };
199+
if (data?.id) return { id: data.id, acct: handle };
203200
}
204201

205202
return null;

0 commit comments

Comments
 (0)