apache / apache/mina-sshd

SCP user friendly exceptions

Open
#401 4 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
1.1k
Forks
400
Avg merge
5d 1h
Merged PRs (30d)
1

Description

### Version

2.10.0

### Bug description

When using the SCP client to upload a file to a remote location that does not exist a `WindowClosedException` is raised instead of a more user friendly SCP exception detailing the reason of why the upload/download failed.

The snippet of code below raises a `WindowClosedException` exception when `/remote/path/that/does/not/exist` doesn't exist.
```
val session = sshClient.connect(
username,
hostname,
port
).verify(5000).session
session.auth().await(5000)

scpClient = ScpClientCreator.instance().createScpClient(session)
scpClient.upload("/local/path/file_name", "/remote/path/that/does/not/exist/file_name", options)
```

### Actual behavior

```
e = {WindowClosedException@37364} "org.apache.sshd.common.channel.WindowClosedException: Already closed: RemoteWindow[client](ChannelExec[id=0, recipient=0]-ClientSessionImpl[ifaur@localhost/127.0.0.1:2222])"
disconnectCode = 0
backtrace = {Object[6]@37368}
detailMessage = "Already closed: RemoteWindow[client](ChannelExec[id=0, recipient=0]-ClientSessionImpl[ifaur@localhost/127.0.0.1:2222])"
cause = {WindowClosedException@37364} "org.apache.sshd.common.channel.WindowClosedException: Already closed: RemoteWindow[client](ChannelExec[id=0, recipient=0]-ClientSessionImpl[ifaur@localhost/127.0.0.1:2222])"
stackTrace = {StackTraceElement[39]@37373}
0 = {StackTraceElement@41979} "org.apache.sshd.common.channel.RemoteWindow.waitForCondition(RemoteWindow.java:230)"
1 = {StackTraceElement@41980} "org.apache.sshd.common.channel.RemoteWindow.waitForSpace(RemoteWindow.java:187)"
2 = {StackTraceElement@41981} "org.apache.sshd.common.channel.ChannelOutputStream.flush(ChannelOutputStream.java:278)"
3 = {StackTraceElement@41982} "org.apache.sshd.scp.common.helpers.ScpIoUtils.writeLine(ScpIoUtils.java:82)"
4 = {StackTraceElement@41983} "org.apache.sshd.scp.common.helpers.ScpIoUtils.sendAcknowledgedCommand(ScpIoUtils.java:94)"
5 = {StackTraceElement@41984} "org.apache.sshd.scp.common.ScpHelper.sendAcknowledgedCommand(ScpHelper.java:724)"
6 = {StackTraceElement@41985} "org.apache.sshd.scp.common.ScpHelper.sendDir(ScpHelper.java:686)"
7 = {StackTraceElement@41986} "org.apache.sshd.scp.common.ScpHelper.send(ScpHelper.java:484)"
8 = {StackTraceElement@41987} "org.apache.sshd.scp.common.ScpHelper.send(ScpHelper.java:454)"
9 = {StackTraceElement@41988} "org.apache.sshd.scp.client.AbstractScpClient.lambda$upload$0(AbstractScpClient.java:143)"
10 = {StackTraceElement@41989} "org.apache.sshd.scp.client.DefaultScpClient.runUpload(DefaultScpClient.java:149)"
11 = {StackTraceElement@41990} "org.apache.sshd.scp.client.AbstractScpClient.upload(AbstractScpClient.java:143)"
12 = {StackTraceElement@41991} "org.apache.sshd.scp.client.ScpClient.upload(ScpClient.java:106)"
```

### Expected behavior

a `SCPException` or even a basic `IOException` with a more relevant message:
- destination "/remote/path/that/does/not/exist/file_name" does not exist or could not be created
- "/remote/path/that/does/not/exist/file_name" no such file or directory

### Relevant log output

_No response_

### Other information

_No response_

Contributor guide

No contributing guide indexed for this repository

Research direction

Trace the SCP upload path from AbstractScpClient.upload and DefaultScpClient.runUpload through ScpHelper.send and ScpIoUtils.sendAcknowledgedCommand. Reproduce the missing-destination case, then ensure it reports a relevant SCPException or IOException with the destination and failure reason instead of WindowClosedException. Done means upload and download failures expose a user-facing error describing the missing or uncreatable path.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
networking
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.