Skip to content

Commit 84449cf

Browse files
committed
fix(plugins): skip broken web provider factories
1 parent 630f0d6 commit 84449cf

2 files changed

Lines changed: 34 additions & 23 deletions

File tree

src/plugins/web-provider-public-artifacts.explicit-fast-path.test.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,12 @@ describe("web provider public artifacts explicit fast path", () => {
144144
expect(loadPluginManifestRegistryMock).not.toHaveBeenCalled();
145145
});
146146

147-
it("throws when every matching bundled web provider factory fails", () => {
148-
expect(() =>
147+
it("skips plugins whose bundled web provider factories all fail", () => {
148+
expect(
149149
resolveBundledWebSearchProvidersFromPublicArtifacts({
150150
onlyPluginIds: ["fuzzplugin"],
151151
}),
152-
).toThrow("Unable to initialize web providers for plugin fuzzplugin");
152+
).toEqual([]);
153153

154154
expect(loadBundledPluginPublicArtifactModuleSyncMock).toHaveBeenCalledWith({
155155
dirName: "fuzzplugin",
@@ -158,6 +158,26 @@ describe("web provider public artifacts explicit fast path", () => {
158158
expect(loadPluginManifestRegistryMock).not.toHaveBeenCalled();
159159
});
160160

161+
it("keeps healthy bundled web providers when another selected plugin factory fails", () => {
162+
const provider = expectSingleProvider(
163+
resolveBundledWebSearchProvidersFromPublicArtifacts({
164+
onlyPluginIds: ["fuzzplugin", "brave"],
165+
}),
166+
);
167+
168+
expect(provider.pluginId).toBe("brave");
169+
expect(provider.id).toBe("brave");
170+
expect(loadBundledPluginPublicArtifactModuleSyncMock).toHaveBeenCalledWith({
171+
dirName: "brave",
172+
artifactBasename: "web-search-contract-api.js",
173+
});
174+
expect(loadBundledPluginPublicArtifactModuleSyncMock).toHaveBeenCalledWith({
175+
dirName: "fuzzplugin",
176+
artifactBasename: "web-search-contract-api.js",
177+
});
178+
expect(loadPluginManifestRegistryMock).not.toHaveBeenCalled();
179+
});
180+
161181
it("resolves bundled runtime web search providers by explicit plugin id", () => {
162182
const provider = expectSingleProvider(
163183
resolveExplicitRuntimeWebSearchProviders({

src/plugins/web-provider-public-artifacts.explicit.ts

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ function collectProviderFactories<TProvider>(params: {
5757
mod: Record<string, unknown>;
5858
suffix: string;
5959
isProvider: (value: unknown) => value is TProvider;
60-
}): { providers: TProvider[]; errors: unknown[] } {
60+
}): { providers: TProvider[]; failedFactoryCount: number } {
6161
const providers: TProvider[] = [];
62-
const errors: unknown[] = [];
62+
let failedFactoryCount = 0;
6363
for (const [name, exported] of Object.entries(params.mod).toSorted(([left], [right]) =>
6464
left.localeCompare(right),
6565
)) {
@@ -74,24 +74,15 @@ function collectProviderFactories<TProvider>(params: {
7474
let candidate: unknown;
7575
try {
7676
candidate = exported();
77-
} catch (error) {
78-
errors.push(error);
77+
} catch {
78+
failedFactoryCount += 1;
7979
continue;
8080
}
8181
if (params.isProvider(candidate)) {
8282
providers.push(candidate);
8383
}
8484
}
85-
return { providers, errors };
86-
}
87-
88-
function unableToInitializeProviderError(params: {
89-
pluginId: string;
90-
errors: readonly unknown[];
91-
}): Error {
92-
return new Error(`Unable to initialize web providers for plugin ${params.pluginId}`, {
93-
cause: params.errors.length === 1 ? params.errors[0] : new AggregateError(params.errors),
94-
});
85+
return { providers, failedFactoryCount };
9586
}
9687

9788
function tryLoadBundledPublicArtifactModule(params: {
@@ -135,17 +126,17 @@ function loadBundledProviderEntriesFromDir<TProvider extends object>(params: {
135126
if (!mod) {
136127
return null;
137128
}
138-
const { providers, errors } = collectProviderFactories({
129+
const { providers, failedFactoryCount } = collectProviderFactories({
139130
mod,
140131
suffix: params.suffix,
141132
isProvider: params.isProvider,
142133
});
143134
if (providers.length === 0) {
144-
if (errors.length > 0) {
145-
throw unableToInitializeProviderError({
146-
pluginId: params.pluginId,
147-
errors,
148-
});
135+
if (failedFactoryCount > 0) {
136+
// A broken plugin-owned provider factory must not poison startup for
137+
// other providers. Treat the plugin as unavailable and let callers keep
138+
// resolving the remaining active provider set.
139+
return [];
149140
}
150141
return null;
151142
}

0 commit comments

Comments
 (0)