Fix: SSH-Befehlsfehler zeigt RouterOS-Fehlertext statt nur Exit-Code

Citadels executeCommand() verwirft die gesammelte Kommandoausgabe,
sobald der Exit-Code ungleich 0 ist -- genau der Text, den RouterOS
bei einem fehlerhaften Befehl zurückgibt (z.B. falscher Parameter,
Interface existiert nicht). Eigene Sammlung über
executeCommandStream() behält die Ausgabe bis zum Fehlschlag und
hängt sie an die Fehlermeldung an.

Aufgefallen beim ersten Schreibtest (M3 "Einrichten"-Tab) gegen
echtes Testgerät: Fehler kam nur als nutzloses
"Citadel.SSHClient.CommandFailed error 1" durch.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HReLXMbmPvtQ23p1iWiJNW
This commit is contained in:
Kay
2026-09-11 21:49:30 +02:00
co-authored by Claude Sonnet 5
parent abe5864ea3
commit 5117386a4e
@@ -62,9 +62,29 @@ final class SSHTransport: RouterOSTransport {
_ = try await run(command.cliLine)
}
/// Runs a command via `executeCommandStream` (not the simpler `executeCommand`), because
/// `executeCommand` discards whatever output it already collected the moment the command
/// exits non-zero exactly the RouterOS error text we need. Collecting the stream ourselves
/// keeps that text available even when the command fails.
private func run(_ command: String) async throws -> String {
guard let client else { throw RouterOSError.notConnected }
let buffer = try await client.executeCommand(command)
return String(buffer: buffer)
var output = ""
do {
let stream = try await client.executeCommandStream(command)
for try await chunk in stream {
switch chunk {
case .stdout(let buffer), .stderr(let buffer):
output += String(buffer: buffer)
}
}
return output
} catch let failure as SSHClient.CommandFailed {
let detail = output.trimmingCharacters(in: .whitespacesAndNewlines)
throw RouterOSError.invalidResponse(
"RouterOS meldete Fehler (Exit-Code \(failure.exitCode)) für \"\(command)\""
+ (detail.isEmpty ? "" : ": \(detail)")
)
}
}
}