fix: fixed a crash when the local directory specified in the auth form does not exist

fix #319
This commit is contained in:
veeso
2025-03-15 16:46:57 +01:00
parent dd35fe825c
commit cdf303a847
6 changed files with 46 additions and 24 deletions

View File

@@ -44,6 +44,8 @@
Released on ??
- [issue 319](https://github.com/veeso/termscp/issues/319): fixed a crash when the local directory specified in the auth form does not exist
- [issue 327](https://github.com/veeso/termscp/issues/327): fixed a panic when trying to go up from local directory on localhost in the auth form
- Dependencies:
- `argh` to `0.1.13`
- `bytesize` to `2`

View File

@@ -342,7 +342,7 @@ impl ActivityManager {
fn run_filetransfer(&mut self) -> Option<NextActivity> {
info!("Starting FileTransferActivity");
// Get context
let ctx: Context = match self.context.take() {
let mut ctx: Context = match self.context.take() {
Some(ctx) => ctx,
None => {
error!("Failed to start FileTransferActivity: context is None");
@@ -367,8 +367,18 @@ impl ActivityManager {
}
};
let mut activity: FileTransferActivity =
FileTransferActivity::new(host_bridge_params, remote_params, self.ticks);
// try to setup activity
let mut activity =
match FileTransferActivity::new(host_bridge_params, remote_params, self.ticks) {
Ok(activity) => activity,
Err(err) => {
error!("Failed to start FileTransferActivity: {}", err);
ctx.set_error(err);
self.context = Some(ctx);
// Return to authentication
return Some(NextActivity::Authentication);
}
};
// Prepare result
let result: Option<NextActivity>;
// Create activity

View File

@@ -7,15 +7,19 @@ pub struct HostBridgeBuilder;
impl HostBridgeBuilder {
/// Build Host Bridge from parms
///
/// if protocol and parameters are inconsistent, the function will panic.
pub fn build(params: HostBridgeParams, config_client: &ConfigClient) -> Box<dyn HostBridge> {
/// if protocol and parameters are inconsistent, the function will return an error.
pub fn build(
params: HostBridgeParams,
config_client: &ConfigClient,
) -> Result<Box<dyn HostBridge>, String> {
match params {
HostBridgeParams::Localhost(path) => {
Box::new(Localhost::new(path).expect("Failed to create Localhost"))
}
HostBridgeParams::Remote(protocol, params) => Box::new(RemoteBridged::from(
RemoteFsBuilder::build(protocol, params, config_client),
)),
HostBridgeParams::Localhost(path) => Localhost::new(path)
.map(|host| Box::new(host) as Box<dyn HostBridge>)
.map_err(|e| e.to_string()),
HostBridgeParams::Remote(protocol, params) => {
RemoteFsBuilder::build(protocol, params, config_client)
.map(|host| Box::new(RemoteBridged::from(host)) as Box<dyn HostBridge>)
}
}
}
}

View File

@@ -37,33 +37,35 @@ impl RemoteFsBuilder {
protocol: FileTransferProtocol,
params: ProtocolParams,
config_client: &ConfigClient,
) -> Box<dyn RemoteFs> {
) -> Result<Box<dyn RemoteFs>, String> {
match (protocol, params) {
(FileTransferProtocol::AwsS3, ProtocolParams::AwsS3(params)) => {
Box::new(Self::aws_s3_client(params))
Ok(Box::new(Self::aws_s3_client(params)))
}
(FileTransferProtocol::Ftp(secure), ProtocolParams::Generic(params)) => {
Box::new(Self::ftp_client(params, secure))
Ok(Box::new(Self::ftp_client(params, secure)))
}
(FileTransferProtocol::Kube, ProtocolParams::Kube(params)) => {
Box::new(Self::kube_client(params))
Ok(Box::new(Self::kube_client(params)))
}
(FileTransferProtocol::Scp, ProtocolParams::Generic(params)) => {
Box::new(Self::scp_client(params, config_client))
Ok(Box::new(Self::scp_client(params, config_client)))
}
(FileTransferProtocol::Sftp, ProtocolParams::Generic(params)) => {
Box::new(Self::sftp_client(params, config_client))
Ok(Box::new(Self::sftp_client(params, config_client)))
}
#[cfg(smb)]
(FileTransferProtocol::Smb, ProtocolParams::Smb(params)) => {
Box::new(Self::smb_client(params))
Ok(Box::new(Self::smb_client(params)))
}
(FileTransferProtocol::WebDAV, ProtocolParams::WebDAV(params)) => {
Box::new(Self::webdav_client(params))
Ok(Box::new(Self::webdav_client(params)))
}
(protocol, params) => {
error!("Invalid params for protocol '{:?}'", protocol);
panic!("Invalid protocol '{protocol:?}' with parameters of type {params:?}")
Err(format!(
"Invalid protocol '{protocol:?}' with parameters of type {params:?}",
))
}
}
}

View File

@@ -243,14 +243,14 @@ impl FileTransferActivity {
host_bridge_params: HostBridgeParams,
remote_params: &FileTransferParams,
ticks: Duration,
) -> Self {
) -> Result<Self, String> {
// Get config client
let config_client: ConfigClient = Self::init_config_client();
// init host bridge
let host_bridge = HostBridgeBuilder::build(host_bridge_params, &config_client);
let host_bridge = HostBridgeBuilder::build(host_bridge_params, &config_client)?;
let host_bridge_connected = host_bridge.is_localhost();
let enable_fs_watcher = host_bridge.is_localhost();
Self {
Ok(Self {
exit_reason: None,
context: None,
app: Application::init(
@@ -264,7 +264,7 @@ impl FileTransferActivity {
remote_params.protocol,
remote_params.params.clone(),
&config_client,
),
)?,
browser: Browser::new(&config_client),
log_records: VecDeque::with_capacity(256), // 256 events is enough I guess
walkdir: WalkdirStates::default(),
@@ -280,7 +280,7 @@ impl FileTransferActivity {
},
host_bridge_connected,
remote_connected: false,
}
})
}
fn host_bridge(&self) -> &FileExplorer {

View File

@@ -108,6 +108,10 @@ impl Context {
pub fn error(&mut self) -> Option<String> {
self.error.take()
}
pub fn set_error(&mut self, error: String) {
self.error = Some(error);
}
}
impl Drop for Context {