mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
Merge pull request #2259 from PR0M3TH3AN/codex/update-fetchhistory-to-handle-registration-errors
Guard watch-history renderer when feed registration is unavailable
This commit is contained in:
2 files changed
+93
-16
No files matched your search
+32
-16
@@ -11,7 +11,7 @@ import {
|
||||
WATCH_HISTORY_BATCH_PAGE_SIZE
|
||||
} from "./config.js";
|
||||
import { getApplication } from "./applicationContext.js";
|
||||
import { userLogger } from "./utils/logger.js";
|
||||
import { devLogger, userLogger } from "./utils/logger.js";
|
||||
import {
|
||||
normalizeVideoModerationContext,
|
||||
applyModerationContextDatasets,
|
||||
@@ -1391,6 +1391,7 @@ export function buildHistoryCard({ item, video, profile, variant }) {
|
||||
}
|
||||
|
||||
export function createWatchHistoryRenderer(config = {}) {
|
||||
let hasLoggedFeedRegistrationFallback = false;
|
||||
const {
|
||||
container = typeof document !== "undefined" ? document : null,
|
||||
fetchHistory = async (
|
||||
@@ -1400,25 +1401,40 @@ export function createWatchHistoryRenderer(config = {}) {
|
||||
const app = getAppInstance();
|
||||
const engine = app?.feedEngine;
|
||||
if (engine && typeof engine.run === "function") {
|
||||
let hasFeedDefinition =
|
||||
typeof engine.getFeedDefinition === "function"
|
||||
? Boolean(engine.getFeedDefinition("watch-history"))
|
||||
: true;
|
||||
// Ensure the watch-history feed is registered. It may not be if the
|
||||
// feed engine was ready but registration was silently skipped during
|
||||
// bootstrap (e.g. timing edge cases).
|
||||
if (
|
||||
typeof engine.getFeedDefinition === "function" &&
|
||||
!engine.getFeedDefinition("watch-history") &&
|
||||
typeof app.registerWatchHistoryFeed === "function"
|
||||
) {
|
||||
app.registerWatchHistoryFeed();
|
||||
if (!hasFeedDefinition && typeof app.registerWatchHistoryFeed === "function") {
|
||||
try {
|
||||
app.registerWatchHistoryFeed();
|
||||
} catch (registerError) {
|
||||
// Fall through to service fallback if registration fails.
|
||||
}
|
||||
hasFeedDefinition =
|
||||
typeof engine.getFeedDefinition === "function"
|
||||
? Boolean(engine.getFeedDefinition("watch-history"))
|
||||
: hasFeedDefinition;
|
||||
}
|
||||
try {
|
||||
const runtime = buildWatchHistoryFeedRuntime({
|
||||
actor: actorInput,
|
||||
cursor,
|
||||
forceRefresh,
|
||||
});
|
||||
return await engine.run("watch-history", { runtime });
|
||||
} catch (feedError) {
|
||||
// Fall through to service fallback if feed is still not registered
|
||||
if (hasFeedDefinition) {
|
||||
try {
|
||||
const runtime = buildWatchHistoryFeedRuntime({
|
||||
actor: actorInput,
|
||||
cursor,
|
||||
forceRefresh,
|
||||
});
|
||||
return await engine.run("watch-history", { runtime });
|
||||
} catch (feedError) {
|
||||
// Fall through to service fallback if feed is still not registered
|
||||
}
|
||||
} else if (!hasLoggedFeedRegistrationFallback) {
|
||||
hasLoggedFeedRegistrationFallback = true;
|
||||
devLogger.info(
|
||||
"[historyView] watch-history feed unavailable after registration attempt; using service fallback.",
|
||||
);
|
||||
}
|
||||
}
|
||||
const items = await watchHistoryService.loadLatest(actorInput, {
|
||||
|
||||
@@ -2392,6 +2392,66 @@ async function testWatchHistoryLocalFallbackWhenDisabled() {
|
||||
}
|
||||
}
|
||||
|
||||
async function testWatchHistoryRendererFeedRegistrationFallback() {
|
||||
console.log("Running watch history renderer feed registration fallback test...");
|
||||
|
||||
const actor = "watch-history-renderer-fallback";
|
||||
const originalApp = getApplication();
|
||||
const originalLoadLatest = watchHistoryService.loadLatest;
|
||||
const originalDocument = globalThis.document;
|
||||
const originalHTMLElement = globalThis.HTMLElement;
|
||||
|
||||
let runCalled = false;
|
||||
let loadLatestCalls = 0;
|
||||
|
||||
try {
|
||||
globalThis.document = { querySelector: () => null };
|
||||
globalThis.HTMLElement = class HTMLElement {};
|
||||
|
||||
watchHistoryService.loadLatest = async (actorInput) => {
|
||||
loadLatestCalls += 1;
|
||||
assert.equal(actorInput, actor, "fallback loader should target provided actor");
|
||||
return [{ type: "e", value: "service-fallback-entry", watchedAt: 1_700_700_000 }];
|
||||
};
|
||||
|
||||
setApplication({
|
||||
feedEngine: {
|
||||
run() {
|
||||
runCalled = true;
|
||||
throw new Error("not registered");
|
||||
},
|
||||
getFeedDefinition() {
|
||||
return null;
|
||||
},
|
||||
},
|
||||
registerWatchHistoryFeed() {
|
||||
throw new Error("registration failed");
|
||||
},
|
||||
isAuthorBlocked: () => false,
|
||||
getHashtagPreferences: () => ({ interests: [], disinterests: [] }),
|
||||
});
|
||||
|
||||
const renderer = createWatchHistoryRenderer({
|
||||
container: { querySelector: () => null },
|
||||
getActor: async () => actor,
|
||||
});
|
||||
|
||||
await renderer.init({ actor, force: true });
|
||||
const state = renderer.getState();
|
||||
|
||||
assert.equal(runCalled, false, "renderer should not run unregistered feed");
|
||||
assert.equal(loadLatestCalls, 1, "renderer should use service fallback once");
|
||||
assert.equal(state.lastError, null, "fallback path should avoid surfacing feed registration errors");
|
||||
assert.equal(state.items.length, 1, "fallback path should populate items from service");
|
||||
assert.equal(state.items[0]?.pointer?.value, "service-fallback-entry");
|
||||
} finally {
|
||||
watchHistoryService.loadLatest = originalLoadLatest;
|
||||
globalThis.document = originalDocument;
|
||||
globalThis.HTMLElement = originalHTMLElement;
|
||||
setApplication(originalApp || null);
|
||||
}
|
||||
}
|
||||
|
||||
async function testWatchHistorySyncEnabledForLoggedInUsers() {
|
||||
console.log("Running watch history logged-in sync override test...");
|
||||
|
||||
@@ -2636,6 +2696,7 @@ await testWatchHistoryStaleCacheRefresh();
|
||||
await testWatchHistoryLocalFallbackWhenDisabled();
|
||||
await testWatchHistorySyncEnabledForLoggedInUsers();
|
||||
await testWatchHistoryAppLoginFallback();
|
||||
await testWatchHistoryRendererFeedRegistrationFallback();
|
||||
await testNormalizeActorKeyShortCircuit();
|
||||
// await testNormalizeActorKeyManualFallback(); // Flaky in env without robust nostr-tools
|
||||
|
||||
|
||||
Reference in new issue
Block a user