mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-07-27 20:29:10 +00:00
75 lines
3.2 KiB
TypeScript
75 lines
3.2 KiB
TypeScript
export interface ErrorRule {
|
|
id: string;
|
|
type: 'startup' | 'runtime' | 'ambiguous';
|
|
pattern: RegExp;
|
|
getMessage: (matches: RegExpMatchArray) => string;
|
|
canSilentlyRollback: boolean;
|
|
}
|
|
|
|
export class ErrorParser {
|
|
private static rules: ErrorRule[] = [
|
|
{
|
|
id: 'PORT_CONFLICT',
|
|
type: 'startup',
|
|
pattern: /(?:bind: address already in use|ports are not available: exposing port TCP [^:]+:(\d+))/,
|
|
getMessage: (m) => `Port ${m[1] || 'conflict'} is already in use by another service on this server.`,
|
|
canSilentlyRollback: true
|
|
},
|
|
{
|
|
id: 'NAME_CONFLICT',
|
|
type: 'startup',
|
|
pattern: /Conflict\. The container name "\/?([^"]+)" is already in use/,
|
|
getMessage: (m) => `A container named '${m[1]}' already exists.`,
|
|
canSilentlyRollback: true
|
|
},
|
|
{
|
|
id: 'YAML_SYNTAX',
|
|
type: 'startup',
|
|
pattern: /(?:yaml: line (\d+):|mapping values are not allowed here)/,
|
|
getMessage: (m) => m[1] ? `Syntax error in compose.yaml near line ${m[1]}.` : `Syntax error in compose.yaml.`,
|
|
canSilentlyRollback: false
|
|
},
|
|
{
|
|
id: 'MISSING_ENV',
|
|
type: 'startup',
|
|
pattern: /(?:invalid interpolation format|required variable ([^\s]+) is missing)/,
|
|
getMessage: (m) => `Missing required environment variable: ${m[1] || 'Check configuration'}.`,
|
|
canSilentlyRollback: false
|
|
},
|
|
{
|
|
id: 'ARCH_MISMATCH',
|
|
type: 'runtime',
|
|
pattern: /(?:exec format error|does not match the specified platform)/i,
|
|
getMessage: () => `Architecture mismatch. This image is not compatible with this server's CPU architecture.`,
|
|
canSilentlyRollback: true
|
|
},
|
|
{
|
|
id: 'MISSING_NETWORK',
|
|
type: 'startup',
|
|
pattern: /network ([^\s]+) declared as external, but could not be found/,
|
|
getMessage: (m) => `The external network '${m[1]}' does not exist.`,
|
|
canSilentlyRollback: false
|
|
},
|
|
{
|
|
id: 'HOST_PORT_CONFLICT',
|
|
type: 'startup',
|
|
pattern: /host-mode networking can not work with published ports/,
|
|
getMessage: () => `Network mode 'host' cannot be combined with explicit port mappings.`,
|
|
canSilentlyRollback: false
|
|
}
|
|
];
|
|
|
|
public static parse(errorOutput: string): { message: string, rule: ErrorRule | null } {
|
|
for (const rule of this.rules) {
|
|
const match = errorOutput.match(rule.pattern);
|
|
if (match) {
|
|
return { message: rule.getMessage(match), rule };
|
|
}
|
|
}
|
|
// Fallback: Extract the last meaningful line, strip Docker progress bars
|
|
const lines = errorOutput.split('\n').map(l => l.trim()).filter(l => l.length > 0 && !l.includes('Downloading') && !l.includes('Extracting') && !l.includes('Pulling') && !l.includes('Download complete'));
|
|
const lastLine = lines.length > 0 ? lines[lines.length - 1] : 'Unknown deployment error occurred.';
|
|
return { message: lastLine, rule: null };
|
|
}
|
|
}
|