fix: guard channel tool listActions (#2859) (thanks @mbelinky)

This commit is contained in:
Shadow
2026-01-27 19:25:14 -06:00
committed by Shadow
parent 4287c21e77
commit 34653e4baf
2 changed files with 54 additions and 0 deletions

View File

@@ -77,6 +77,7 @@ Status: beta.
- macOS: auto-scroll to bottom when sending a new message while scrolled up. (#2471) Thanks @kennyklee.
- Web UI: auto-expand the chat compose textarea while typing (with sensible max height). (#2950) Thanks @shivamraut101.
- Gateway: prevent crashes on transient network errors (fetch failures, timeouts, DNS). Added fatal error detection to only exit on truly critical errors. Fixes #2895, #2879, #2873. (#2980) Thanks @elliotsecops.
- Agents: guard channel tool listActions to avoid plugin crashes. (#2859) Thanks @mbelinky.
- Gateway: suppress AbortError and transient network errors in unhandled rejections. (#2451) Thanks @Glucksberg.
- TTS: keep /tts status replies on text-only commands and avoid duplicate block-stream audio. (#2451) Thanks @Glucksberg.
- Security: pin npm overrides to keep tar@7.5.4 for install toolchains.

View File

@@ -0,0 +1,53 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { MoltbotConfig } from "../config/config.js";
import type { ChannelPlugin } from "../channels/plugins/types.js";
import { setActivePluginRegistry } from "../plugins/runtime.js";
import { createTestRegistry } from "../test-utils/channel-plugins.js";
import { defaultRuntime } from "../runtime.js";
import { __testing, listAllChannelSupportedActions } from "./channel-tools.js";
describe("channel tools", () => {
const errorSpy = vi.spyOn(defaultRuntime, "error").mockImplementation(() => undefined);
beforeEach(() => {
const plugin: ChannelPlugin = {
id: "test",
meta: {
id: "test",
label: "Test",
selectionLabel: "Test",
docsPath: "/channels/test",
blurb: "test plugin",
},
capabilities: { chatTypes: ["direct"] },
config: {
listAccountIds: () => [],
resolveAccount: () => ({}),
},
actions: {
listActions: () => {
throw new Error("boom");
},
},
};
__testing.resetLoggedListActionErrors();
errorSpy.mockClear();
setActivePluginRegistry(createTestRegistry([{ pluginId: "test", source: "test", plugin }]));
});
afterEach(() => {
setActivePluginRegistry(createTestRegistry([]));
errorSpy.mockClear();
});
it("skips crashing plugins and logs once", () => {
const cfg = {} as MoltbotConfig;
expect(listAllChannelSupportedActions({ cfg })).toEqual([]);
expect(errorSpy).toHaveBeenCalledTimes(1);
expect(listAllChannelSupportedActions({ cfg })).toEqual([]);
expect(errorSpy).toHaveBeenCalledTimes(1);
});
});