mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 09:20:43 +00:00
fix: add plugin load debug shape
This commit is contained in:
@@ -294,6 +294,10 @@ openclaw plugins doctor
|
||||
compatibility notices. When everything is clean it prints `No plugin issues
|
||||
detected.`
|
||||
|
||||
For module-shape failures such as missing `register`/`activate` exports, rerun
|
||||
with `OPENCLAW_PLUGIN_LOAD_DEBUG=1` to include a compact export-shape summary in
|
||||
the diagnostic output.
|
||||
|
||||
### Marketplace
|
||||
|
||||
```bash
|
||||
|
||||
@@ -3531,6 +3531,31 @@ module.exports = { id: "throws-after-import", register() {} };`,
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("can include plugin export shape when register is missing", () => {
|
||||
useNoBundledPlugins();
|
||||
const plugin = writePlugin({
|
||||
id: "missing-register-shape",
|
||||
filename: "missing-register-shape.cjs",
|
||||
body: `module.exports = { default: { default: { id: "missing-register-shape" } } };`,
|
||||
});
|
||||
|
||||
const registry = withEnv({ OPENCLAW_PLUGIN_LOAD_DEBUG: "1" }, () =>
|
||||
loadRegistryFromSinglePlugin({
|
||||
plugin,
|
||||
pluginConfig: {
|
||||
allow: ["missing-register-shape"],
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
const loaded = registry.plugins.find((entry) => entry.id === "missing-register-shape");
|
||||
expect(loaded?.status).toBe("error");
|
||||
expect(loaded?.error).toContain("plugin export missing register/activate");
|
||||
expect(loaded?.error).toContain("module shape:");
|
||||
expect(loaded?.error).toContain("export:object keys=default");
|
||||
expect(loaded?.error).toContain("export.default:object keys=default");
|
||||
});
|
||||
|
||||
it("handles single-plugin channel, context engine, and cli validation", () => {
|
||||
useNoBundledPlugins();
|
||||
const scenarios = [
|
||||
|
||||
@@ -1022,6 +1022,53 @@ function resolvePluginModuleExport(moduleExport: unknown): {
|
||||
return {};
|
||||
}
|
||||
|
||||
function isPluginLoadDebugEnabled(env: NodeJS.ProcessEnv): boolean {
|
||||
const normalized = normalizeLowercaseStringOrEmpty(env.OPENCLAW_PLUGIN_LOAD_DEBUG);
|
||||
return normalized === "1" || normalized === "true" || normalized === "yes" || normalized === "on";
|
||||
}
|
||||
|
||||
function describePluginModuleExportShape(
|
||||
value: unknown,
|
||||
label = "export",
|
||||
seen: Set<unknown> = new Set(),
|
||||
): string[] {
|
||||
if (value === null) {
|
||||
return [`${label}:null`];
|
||||
}
|
||||
if (typeof value !== "object") {
|
||||
return [`${label}:${typeof value}`];
|
||||
}
|
||||
if (seen.has(value)) {
|
||||
return [`${label}:circular`];
|
||||
}
|
||||
seen.add(value);
|
||||
|
||||
const record = value as Record<string, unknown>;
|
||||
const keys = Object.keys(record).toSorted();
|
||||
const visibleKeys = keys.slice(0, 8);
|
||||
const extraCount = keys.length - visibleKeys.length;
|
||||
const keySummary =
|
||||
visibleKeys.length > 0
|
||||
? `${visibleKeys.join(",")}${extraCount > 0 ? `,+${extraCount}` : ""}`
|
||||
: "none";
|
||||
const details = [`${label}:object keys=${keySummary}`];
|
||||
|
||||
for (const key of ["default", "module", "register", "activate"]) {
|
||||
if (Object.prototype.hasOwnProperty.call(record, key)) {
|
||||
details.push(...describePluginModuleExportShape(record[key], `${label}.${key}`, seen));
|
||||
}
|
||||
}
|
||||
return details;
|
||||
}
|
||||
|
||||
function formatMissingPluginRegisterError(moduleExport: unknown, env: NodeJS.ProcessEnv): string {
|
||||
const message = "plugin export missing register/activate";
|
||||
if (!isPluginLoadDebugEnabled(env)) {
|
||||
return message;
|
||||
}
|
||||
return `${message} (module shape: ${describePluginModuleExportShape(moduleExport).join("; ")})`;
|
||||
}
|
||||
|
||||
function mergeChannelPluginSection<T>(
|
||||
baseValue: T | undefined,
|
||||
overrideValue: T | undefined,
|
||||
@@ -2511,7 +2558,7 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi
|
||||
|
||||
if (typeof register !== "function") {
|
||||
logger.error(`[plugins] ${record.id} missing register/activate export`);
|
||||
pushPluginLoadError("plugin export missing register/activate");
|
||||
pushPluginLoadError(formatMissingPluginRegisterError(mod, env));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2934,7 +2981,7 @@ export async function loadOpenClawPluginCliRegistry(
|
||||
|
||||
if (typeof register !== "function") {
|
||||
logger.error(`[plugins] ${record.id} missing register/activate export`);
|
||||
pushPluginLoadError("plugin export missing register/activate");
|
||||
pushPluginLoadError(formatMissingPluginRegisterError(mod, env));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user