Stabilize gateway reload/restart behavior and remove doctor --json dependency (#504)
This commit is contained in:
committed by
GitHub
Unverified
parent
89bda3c7af
commit
7f3408559d
@@ -716,6 +716,65 @@ export interface ValidationResult {
|
||||
warnings: string[];
|
||||
}
|
||||
|
||||
const DOCTOR_PARSER_FALLBACK_HINT =
|
||||
'Doctor output could not be confidently interpreted; falling back to local channel config checks.';
|
||||
|
||||
type DoctorValidationParseResult = {
|
||||
errors: string[];
|
||||
warnings: string[];
|
||||
undetermined: boolean;
|
||||
};
|
||||
|
||||
export function parseDoctorValidationOutput(channelType: string, output: string): DoctorValidationParseResult {
|
||||
const errors: string[] = [];
|
||||
const warnings: string[] = [];
|
||||
const normalizedChannelType = channelType.toLowerCase();
|
||||
const normalizedOutput = output.trim();
|
||||
|
||||
if (!normalizedOutput) {
|
||||
return {
|
||||
errors,
|
||||
warnings: [DOCTOR_PARSER_FALLBACK_HINT],
|
||||
undetermined: true,
|
||||
};
|
||||
}
|
||||
|
||||
const lines = output
|
||||
.split('\n')
|
||||
.map((line) => line.trim())
|
||||
.filter(Boolean);
|
||||
const channelLines = lines.filter((line) => line.toLowerCase().includes(normalizedChannelType));
|
||||
let classifiedCount = 0;
|
||||
|
||||
for (const line of channelLines) {
|
||||
const lowerLine = line.toLowerCase();
|
||||
if (lowerLine.includes('error') || lowerLine.includes('unrecognized key')) {
|
||||
errors.push(line);
|
||||
classifiedCount += 1;
|
||||
continue;
|
||||
}
|
||||
if (lowerLine.includes('warning')) {
|
||||
warnings.push(line);
|
||||
classifiedCount += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (channelLines.length === 0 || classifiedCount === 0) {
|
||||
warnings.push(DOCTOR_PARSER_FALLBACK_HINT);
|
||||
return {
|
||||
errors,
|
||||
warnings,
|
||||
undetermined: true,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
errors,
|
||||
warnings,
|
||||
undetermined: false,
|
||||
};
|
||||
}
|
||||
|
||||
export interface CredentialValidationResult {
|
||||
valid: boolean;
|
||||
errors: string[];
|
||||
@@ -853,34 +912,41 @@ export async function validateChannelConfig(channelType: string): Promise<Valida
|
||||
|
||||
// Run openclaw doctor command to validate config (async to avoid
|
||||
// blocking the main thread).
|
||||
const output = await new Promise<string>((resolve, reject) => {
|
||||
exec(
|
||||
`node openclaw.mjs doctor --json 2>&1`,
|
||||
{
|
||||
cwd: openclawPath,
|
||||
encoding: 'utf-8',
|
||||
timeout: 30000,
|
||||
windowsHide: true,
|
||||
},
|
||||
(err, stdout) => {
|
||||
if (err) reject(err);
|
||||
else resolve(stdout);
|
||||
},
|
||||
);
|
||||
});
|
||||
const runDoctor = async (command: string): Promise<string> =>
|
||||
await new Promise<string>((resolve, reject) => {
|
||||
exec(
|
||||
command,
|
||||
{
|
||||
cwd: openclawPath,
|
||||
encoding: 'utf-8',
|
||||
timeout: 30000,
|
||||
windowsHide: true,
|
||||
},
|
||||
(err, stdout, stderr) => {
|
||||
const combined = `${stdout || ''}${stderr || ''}`;
|
||||
if (err) {
|
||||
const next = new Error(combined || err.message);
|
||||
reject(next);
|
||||
return;
|
||||
}
|
||||
resolve(combined);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
const lines = output.split('\n');
|
||||
for (const line of lines) {
|
||||
const lowerLine = line.toLowerCase();
|
||||
if (lowerLine.includes(channelType) && lowerLine.includes('error')) {
|
||||
result.errors.push(line.trim());
|
||||
result.valid = false;
|
||||
} else if (lowerLine.includes(channelType) && lowerLine.includes('warning')) {
|
||||
result.warnings.push(line.trim());
|
||||
} else if (lowerLine.includes('unrecognized key') && lowerLine.includes(channelType)) {
|
||||
result.errors.push(line.trim());
|
||||
result.valid = false;
|
||||
}
|
||||
const output = await runDoctor(`node openclaw.mjs doctor 2>&1`);
|
||||
|
||||
const parsedDoctor = parseDoctorValidationOutput(channelType, output);
|
||||
result.errors.push(...parsedDoctor.errors);
|
||||
result.warnings.push(...parsedDoctor.warnings);
|
||||
if (parsedDoctor.errors.length > 0) {
|
||||
result.valid = false;
|
||||
}
|
||||
if (parsedDoctor.undetermined) {
|
||||
logger.warn('Doctor output parsing fell back to local channel checks', {
|
||||
channelType,
|
||||
hint: DOCTOR_PARSER_FALLBACK_HINT,
|
||||
});
|
||||
}
|
||||
|
||||
const config = await readOpenClawConfig();
|
||||
|
||||
Reference in New Issue
Block a user