Skip to content

Commit

Permalink
Merge pull request #58 from orlandos-nl/jo/throw-exit-code-nonzero
Browse files Browse the repository at this point in the history
Throw `SSHClient.CommandFailed` when the status code is non-zero
  • Loading branch information
Joannis authored Feb 27, 2024
2 parents 473464c + 54897d9 commit 6717f73
Showing 1 changed file with 19 additions and 2 deletions.
21 changes: 19 additions & 2 deletions Sources/Citadel/TTY/Client/TTY.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ public struct ExecCommandStream {
stderr.finish(throwing: error)
case .channelSuccess:
()
case .exit(0):
stdout.finish()
stderr.finish()
case .exit(let status):
stdout.finish(throwing: SSHClient.CommandFailed(exitCode: status))
stderr.finish(throwing: SSHClient.CommandFailed(exitCode: status))
}
}
}
Expand All @@ -43,6 +49,7 @@ final class ExecCommandHandler: ChannelDuplexHandler {
case stdout(ByteBuffer)
case stderr(ByteBuffer)
case eof(Error?)
case exit(Int)
}

typealias InboundIn = SSHChannelData
Expand Down Expand Up @@ -70,8 +77,8 @@ final class ExecCommandHandler: ChannelDuplexHandler {
onOutput(context.channel, .channelSuccess)
case is NIOSSH.ChannelFailureEvent:
onOutput(context.channel, .eof(CitadelError.channelFailure))
case is SSHChannelRequestEvent.ExitStatus:
()
case let status as SSHChannelRequestEvent.ExitStatus:
onOutput(context.channel, .exit(status.exitStatus))
default:
context.fireUserInboundEventTriggered(event)
}
Expand Down Expand Up @@ -106,6 +113,10 @@ final class ExecCommandHandler: ChannelDuplexHandler {
}

extension SSHClient {
public struct CommandFailed: Error {
public let exitCode: Int
}

/// Executes a command on the remote server. This will return the output of the command (stdout). If the command fails, the error will be thrown. If the output is too large, the command will fail.
/// - Parameters:
/// - command: The command to execute.
Expand Down Expand Up @@ -165,6 +176,12 @@ extension SSHClient {
channel.writeAndFlush(commandData, promise: nil)
hasReceivedChannelSuccess = true
}
case .exit(let status):
if status == 0 {
streamContinuation.finish()
} else {
streamContinuation.finish(throwing: CommandFailed(exitCode: status))
}
}
}

Expand Down

0 comments on commit 6717f73

Please sign in to comment.