refactor(tests+frontend): one http_sink helper for the hook tests; apiErrorMessage replaces ten hand-rolled error-body parses; type X, import specifiers are not definitions (#2904, milestone 299 step 6)
CI & Build / Python lint (push) Successful in 4s
CI & Build / Plugin hooks (push) Failing after 9s
CI & Build / integration (push) Successful in 28s
CI & Build / TypeScript typecheck (push) Successful in 33s
CI & Build / Python tests (push) Successful in 1m11s
CI & Build / Build & push image (push) Successful in 38s
CI & Build / Python lint (push) Successful in 4s
CI & Build / Plugin hooks (push) Failing after 9s
CI & Build / integration (push) Successful in 28s
CI & Build / TypeScript typecheck (push) Successful in 33s
CI & Build / Python tests (push) Successful in 1m11s
CI & Build / Build & push image (push) Successful in 38s
tests/helpers.http_sink replaces three module-local _Sink handlers (the
write-path tests and the after-write test). ProjectView + SettingsView
parsed `(e as {body?:{error?}}).body?.error || fallback` by hand ten times
beside the apiErrorMessage canon (#2853) - all ten now call it. The
extractor (server + the hook awk mirror) no longer reads `import { type Foo }`
as a definition of Foo - that was the last "identical body" sym family.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -780,8 +780,7 @@ async function saveConnection() {
|
||||
connFormOpen.value = false;
|
||||
await loadForgeConnections();
|
||||
} catch (e) {
|
||||
const body = (e as { body?: { error?: string } }).body;
|
||||
toastStore.show(body?.error || "Failed to save forge connection", "error");
|
||||
toastStore.show(apiErrorMessage(e, "Failed to save forge connection"), "error");
|
||||
} finally {
|
||||
savingConn.value = false;
|
||||
}
|
||||
@@ -793,8 +792,7 @@ async function removeConnection(id: number) {
|
||||
connTestResult.value = null;
|
||||
await loadForgeConnections();
|
||||
} catch (e) {
|
||||
const body = (e as { body?: { error?: string } }).body;
|
||||
toastStore.show(body?.error || "Failed to delete forge connection", "error");
|
||||
toastStore.show(apiErrorMessage(e, "Failed to delete forge connection"), "error");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -810,10 +808,9 @@ async function testConnection(id: number) {
|
||||
message: `Connected — ${res.version}, authenticated as ${res.username}`,
|
||||
};
|
||||
} catch (e) {
|
||||
const body = (e as { body?: { error?: string } }).body;
|
||||
connTestResult.value = {
|
||||
id, ok: false,
|
||||
message: body?.error || "Connection test failed",
|
||||
message: apiErrorMessage(e, "Connection test failed"),
|
||||
};
|
||||
} finally {
|
||||
testingConnId.value = 0;
|
||||
@@ -830,8 +827,7 @@ async function saveForgeWebhook() {
|
||||
forgeWebhookSaved.value = true;
|
||||
setTimeout(() => (forgeWebhookSaved.value = false), 2000);
|
||||
} catch (e) {
|
||||
const body = (e as { body?: { error?: string } }).body;
|
||||
toastStore.show(body?.error || "Failed to save webhook secret", "error");
|
||||
toastStore.show(apiErrorMessage(e, "Failed to save webhook secret"), "error");
|
||||
} finally {
|
||||
savingForgeWebhook.value = false;
|
||||
}
|
||||
@@ -864,8 +860,7 @@ async function saveMarketplaceUrl() {
|
||||
marketplaceUrlSaved.value = true;
|
||||
setTimeout(() => (marketplaceUrlSaved.value = false), 2000);
|
||||
} catch (e) {
|
||||
const body = (e as { body?: { error?: string } }).body;
|
||||
toastStore.show(body?.error || "Failed to save marketplace URL", "error");
|
||||
toastStore.show(apiErrorMessage(e, "Failed to save marketplace URL"), "error");
|
||||
} finally {
|
||||
savingMarketplaceUrl.value = false;
|
||||
}
|
||||
@@ -882,8 +877,7 @@ async function saveDbMaintenance() {
|
||||
dbMaintSaved.value = true;
|
||||
setTimeout(() => (dbMaintSaved.value = false), 2000);
|
||||
} catch (e) {
|
||||
const body = (e as { body?: { error?: string } }).body;
|
||||
toastStore.show(body?.error || "Failed to save maintenance settings", "error");
|
||||
toastStore.show(apiErrorMessage(e, "Failed to save maintenance settings"), "error");
|
||||
} finally {
|
||||
savingDbMaint.value = false;
|
||||
}
|
||||
@@ -912,8 +906,7 @@ async function runDbMaintenanceNow() {
|
||||
);
|
||||
await loadDbHealth(); // reflect the dead-tuple drop
|
||||
} catch (e) {
|
||||
const body = (e as { body?: { error?: string } }).body;
|
||||
toastStore.show(body?.error || "Maintenance run failed", "error");
|
||||
toastStore.show(apiErrorMessage(e, "Maintenance run failed"), "error");
|
||||
} finally {
|
||||
runningDbMaint.value = false;
|
||||
}
|
||||
@@ -1144,8 +1137,7 @@ async function sendInvite() {
|
||||
inviteEmail.value = "";
|
||||
await fetchInvitations();
|
||||
} catch (e: unknown) {
|
||||
const body = (e as { body?: { error?: string } })?.body;
|
||||
toastStore.show(body?.error || "Failed to send invitation", "error");
|
||||
toastStore.show(apiErrorMessage(e, "Failed to send invitation"), "error");
|
||||
} finally {
|
||||
sendingInvite.value = false;
|
||||
}
|
||||
@@ -1196,8 +1188,7 @@ async function deleteUser(userId: number) {
|
||||
users.value = users.value.filter((u) => u.id !== userId);
|
||||
toastStore.show("User deleted");
|
||||
} catch (e: unknown) {
|
||||
const body = (e as { body?: { error?: string } })?.body;
|
||||
toastStore.show(body?.error || "Failed to delete user", "error");
|
||||
toastStore.show(apiErrorMessage(e, "Failed to delete user"), "error");
|
||||
} finally {
|
||||
deleting.value = null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user