mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 09:10:45 +00:00
fix(runtime): harden dependency install surfaces (#71997)
* fix(runtime): harden dependency surfaces * fix(runtime): harden dependency install surfaces * fix(runtime): address dependency surface review * fix(runtime): address dependency surface review * fix(channels): avoid read-only plugin loader cycle * fix(channels): allow optional read-only loader workspace * test(commands): refresh current main checks * test(commands): keep provider metadata mock unique * test(commands): keep doctor security read-only mock unique
This commit is contained in:
@@ -5,7 +5,6 @@ import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import process from "node:process";
|
||||
import { pathToFileURL } from "node:url";
|
||||
import chokidar from "chokidar";
|
||||
import { isRestartRelevantRunNodePath, runNodeWatchedPaths } from "./run-node.mjs";
|
||||
|
||||
const WATCH_NODE_RUNNER = "scripts/run-node.mjs";
|
||||
@@ -120,6 +119,39 @@ const logWatcher = (message, deps) => {
|
||||
deps.process.stderr?.write?.(`[openclaw] ${message}\n`);
|
||||
};
|
||||
|
||||
const isInvalidPackageConfigError = (err) => err?.code === "ERR_INVALID_PACKAGE_CONFIG";
|
||||
|
||||
const extractInvalidPackageConfigPath = (err) => {
|
||||
const message = String(err?.message ?? "");
|
||||
const match = message.match(/Invalid package config (.+?) while importing /);
|
||||
return match?.[1] ?? null;
|
||||
};
|
||||
|
||||
const printFriendlyWatchStartupError = (err) => {
|
||||
const packageConfigPath = extractInvalidPackageConfigPath(err);
|
||||
|
||||
console.error("");
|
||||
console.error(
|
||||
"[openclaw] gateway:watch could not start because a dependency package config looks corrupted.",
|
||||
);
|
||||
if (packageConfigPath) {
|
||||
console.error(`[openclaw] Invalid package config: ${packageConfigPath}`);
|
||||
}
|
||||
console.error("[openclaw] This usually means a file in node_modules is empty or truncated.");
|
||||
console.error("[openclaw] Recommended recovery:");
|
||||
console.error("[openclaw] rm -rf node_modules");
|
||||
console.error("[openclaw] pnpm store prune");
|
||||
console.error("[openclaw] pnpm install");
|
||||
console.error("");
|
||||
console.error("[openclaw] Original error:");
|
||||
console.error(err);
|
||||
};
|
||||
|
||||
const loadChokidar = async () => {
|
||||
const mod = await import("chokidar");
|
||||
return mod.default ?? mod;
|
||||
};
|
||||
|
||||
const waitForWatcherRelease = async (lockPath, pid, deps) => {
|
||||
const deadline = deps.now() + WATCH_LOCK_WAIT_MS;
|
||||
while (deps.now() < deadline) {
|
||||
@@ -212,6 +244,19 @@ const releaseWatchLock = (lockHandle) => {
|
||||
* }} [params]
|
||||
*/
|
||||
export async function runWatchMain(params = {}) {
|
||||
let createWatcher = params.createWatcher;
|
||||
if (!createWatcher) {
|
||||
try {
|
||||
const chokidarModule = await (params.loadChokidar ?? loadChokidar)();
|
||||
createWatcher = (watchPaths, options) => chokidarModule.watch(watchPaths, options);
|
||||
} catch (err) {
|
||||
if (isInvalidPackageConfigError(err)) {
|
||||
printFriendlyWatchStartupError(err);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
const deps = {
|
||||
spawn: params.spawn ?? spawn,
|
||||
process: params.process ?? process,
|
||||
@@ -222,8 +267,7 @@ export async function runWatchMain(params = {}) {
|
||||
sleep: params.sleep ?? sleep,
|
||||
signalProcess: params.signalProcess ?? ((pid, signal) => process.kill(pid, signal)),
|
||||
lockDisabled: params.lockDisabled === true,
|
||||
createWatcher:
|
||||
params.createWatcher ?? ((watchPaths, options) => chokidar.watch(watchPaths, options)),
|
||||
createWatcher,
|
||||
watchPaths: params.watchPaths ?? runNodeWatchedPaths,
|
||||
};
|
||||
|
||||
@@ -363,7 +407,9 @@ if (import.meta.url === pathToFileURL(process.argv[1] ?? "").href) {
|
||||
void runWatchMain()
|
||||
.then((code) => process.exit(code))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
if (!isInvalidPackageConfigError(err)) {
|
||||
console.error(err);
|
||||
}
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user