Skip to content

Commit a858939

Browse files
committed
fix(desktop): harden cleanup fallback and runtime version detection
1 parent 07bb9d2 commit a858939

3 files changed

Lines changed: 259 additions & 98 deletions

File tree

astrbot/core/utils/pip_installer.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -439,9 +439,17 @@ async def install(
439439
wheel_only: bool = False,
440440
) -> None:
441441
args = ["install"]
442-
pip_install_args = (
443-
shlex.split(self.pip_install_arg) if self.pip_install_arg else []
444-
)
442+
pip_install_args: list[str] = []
443+
if self.pip_install_arg:
444+
try:
445+
pip_install_args = shlex.split(self.pip_install_arg)
446+
except ValueError as exc:
447+
logger.warning(
448+
"Failed to parse pip_install_arg with shlex (%s). "
449+
"Falling back to legacy whitespace split.",
450+
exc,
451+
)
452+
pip_install_args = self.pip_install_arg.split()
445453
requested_requirements: set[str] = set()
446454
if package_name:
447455
args.append(package_name)

desktop/lib/backend-manager.js

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -858,16 +858,20 @@ class BackendManager {
858858
}
859859

860860
buildWindowsUnmanagedBackendMatcher(backendConfig) {
861-
const expectedImageName = path.basename(backendConfig.cmd || 'python.exe').toLowerCase();
861+
const safeBackendConfig =
862+
backendConfig && typeof backendConfig === 'object' ? backendConfig : {};
863+
const expectedImageName = path
864+
.basename(safeBackendConfig.cmd || 'python.exe')
865+
.toLowerCase();
862866
const requireStrictCommandLineCheck =
863867
this.isGenericWindowsPythonImage(expectedImageName);
864868
const expectedCommandLineMarkers = [];
865-
if (Array.isArray(backendConfig.args) && backendConfig.args.length > 0) {
866-
const primaryArg = backendConfig.args[0];
869+
if (Array.isArray(safeBackendConfig.args) && safeBackendConfig.args.length > 0) {
870+
const primaryArg = safeBackendConfig.args[0];
867871
if (typeof primaryArg === 'string' && primaryArg) {
868872
const resolvedPrimaryArg = path.isAbsolute(primaryArg)
869873
? primaryArg
870-
: path.resolve(backendConfig.cwd || process.cwd(), primaryArg);
874+
: path.resolve(safeBackendConfig.cwd || process.cwd(), primaryArg);
871875
expectedCommandLineMarkers.push(
872876
this.normalizeWindowsPathForMatch(resolvedPrimaryArg),
873877
);
@@ -884,6 +888,18 @@ class BackendManager {
884888
};
885889
}
886890

891+
buildFallbackWindowsUnmanagedBackendMatcher() {
892+
const fallbackCmdRaw = process.env.ASTRBOT_BACKEND_CMD || 'python.exe';
893+
const fallbackCmd = String(fallbackCmdRaw).trim().split(/\s+/, 1)[0] || 'python.exe';
894+
return {
895+
expectedImageName: path.basename(fallbackCmd).toLowerCase(),
896+
// Fallback mode only checks image name to avoid false negatives
897+
// when backend config is unavailable in current session.
898+
requireStrictCommandLineCheck: false,
899+
expectedCommandLineMarkers: [],
900+
};
901+
}
902+
887903
shouldKillUnmanagedBackendProcess(pid, processInfo, processMatcher) {
888904
const actualImageName = processInfo.imageName.toLowerCase();
889905
if (actualImageName !== processMatcher.expectedImageName) {
@@ -944,8 +960,25 @@ class BackendManager {
944960
`Attempting unmanaged backend cleanup by port=${port} pids=${pids.join(',')}`,
945961
);
946962

947-
const backendConfig = this.getBackendConfig();
948-
const processMatcher = this.buildWindowsUnmanagedBackendMatcher(backendConfig);
963+
let backendConfig = null;
964+
try {
965+
backendConfig = this.getBackendConfig();
966+
} catch (error) {
967+
this.log(
968+
`Failed to resolve backend config during unmanaged cleanup: ${
969+
error instanceof Error ? error.message : String(error)
970+
}`,
971+
);
972+
}
973+
const hasBackendConfig = backendConfig && typeof backendConfig === 'object';
974+
const processMatcher = hasBackendConfig
975+
? this.buildWindowsUnmanagedBackendMatcher(backendConfig)
976+
: this.buildFallbackWindowsUnmanagedBackendMatcher();
977+
if (!hasBackendConfig) {
978+
this.log(
979+
'Backend config is unavailable during unmanaged cleanup; falling back to image-name-only matching.',
980+
);
981+
}
949982

950983
for (const pid of pids) {
951984
const processInfo = this.getWindowsProcessInfo(pid);

0 commit comments

Comments
 (0)