From fa1a80ef5791d88f98d08aba07f65b317bd423d0 Mon Sep 17 00:00:00 2001 From: Mariotaku Date: Thu, 22 Jun 2023 11:50:33 +0900 Subject: [PATCH] more user friendly message for sftp errors --- src-tauri/src/conn_pool/connection.rs | 2 +- src-tauri/src/error.rs | 50 +++++++++++++++++++++++---- src-tauri/src/plugins/devmode.rs | 2 +- 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/src-tauri/src/conn_pool/connection.rs b/src-tauri/src/conn_pool/connection.rs index b38c7b9d..0b98c546 100644 --- a/src-tauri/src/conn_pool/connection.rs +++ b/src-tauri/src/conn_pool/connection.rs @@ -3,7 +3,7 @@ use std::ops::{Deref, DerefMut}; use std::sync::Mutex; use std::time::Duration; -use libssh_rs::{AuthStatus, LogLevel, Session, SshKey, SshOption}; +use libssh_rs::{AuthStatus, Session, SshKey, SshOption}; use uuid::Uuid; use crate::conn_pool::DeviceConnection; diff --git a/src-tauri/src/error.rs b/src-tauri/src/error.rs index ef24212a..d869bf5c 100644 --- a/src-tauri/src/error.rs +++ b/src-tauri/src/error.rs @@ -1,7 +1,10 @@ -use libssh_rs::Error as SshError; -use serde::{Serialize, Serializer}; use std::error::Error as ErrorTrait; use std::fmt::{Debug, Display, Formatter}; +use std::io::ErrorKind; +use std::str::FromStr; + +use libssh_rs::{Error as SshError, SftpError}; +use serde::{Serialize, Serializer}; #[derive(Debug, Serialize, Clone)] #[serde(tag = "reason")] @@ -19,7 +22,7 @@ pub enum Error { }, IO { #[serde(serialize_with = "as_debug_string")] - code: std::io::ErrorKind, + code: ErrorKind, message: String, }, Message { @@ -42,6 +45,12 @@ impl Error { message: String::from("Bad configuration"), }; } + pub fn io(kind: ErrorKind) -> Error { + return Error::IO { + code: kind, + message: kind.to_string(), + }; + } } impl ErrorTrait for Error {} @@ -85,7 +94,7 @@ impl From for Error { message: format!("SSH Error: {s}"), }, SshError::TryAgain => Error::IO { - code: std::io::ErrorKind::WouldBlock, + code: ErrorKind::WouldBlock, message: format!("Would block"), }, SshError::Fatal(s) => { @@ -94,13 +103,13 @@ impl From for Error { Error::Disconnected } else { Error::IO { - code: std::io::ErrorKind::Other, + code: ErrorKind::Other, message: String::from(socket_error), } }; } else if s == "Connection refused" { return Error::IO { - code: std::io::ErrorKind::ConnectionRefused, + code: ErrorKind::ConnectionRefused, message: format!("Connection refused by host"), }; } else if s.starts_with("Timeout connecting to ") { @@ -112,11 +121,38 @@ impl From for Error { message: format!("SSH Error: {s}"), } } - SshError::Sftp(e) => Error::new(format!("SFTP Error: {:?}", e)), + SshError::Sftp(e) => e.into(), }; } } +impl From for Error { + fn from(value: SftpError) -> Self { + let message = value.to_string(); + if let Some(code) = message + .strip_prefix("Sftp error code ") + .and_then(|s| u32::from_str(s).ok()) + { + return match code { + libssh_rs_sys::SSH_FX_EOF => Error::io(ErrorKind::UnexpectedEof), + libssh_rs_sys::SSH_FX_NO_SUCH_FILE => Error::io(ErrorKind::NotFound), + libssh_rs_sys::SSH_FX_PERMISSION_DENIED => Error::io(ErrorKind::PermissionDenied), + libssh_rs_sys::SSH_FX_FAILURE => Error::new("Failed to perform this operation"), + libssh_rs_sys::SSH_FX_NO_CONNECTION => Error::Disconnected, + libssh_rs_sys::SSH_FX_CONNECTION_LOST => Error::Disconnected, + libssh_rs_sys::SSH_FX_NO_SUCH_PATH => Error::io(ErrorKind::NotFound), + libssh_rs_sys::SSH_FX_FILE_ALREADY_EXISTS => Error::io(ErrorKind::AlreadyExists), + libssh_rs_sys::SSH_FX_WRITE_PROTECT => Error::IO { + code: ErrorKind::Other, + message: String::from("SSH_FX_WRITE_PROTECT"), + }, + _ => Error::Message { message }, + }; + } + return Error::Message { message }; + } +} + impl From> for Error { fn from(value: Box) -> Self { return Error::new(format!("{:?}", value)); diff --git a/src-tauri/src/plugins/devmode.rs b/src-tauri/src/plugins/devmode.rs index f7258e29..3cae25b0 100644 --- a/src-tauri/src/plugins/devmode.rs +++ b/src-tauri/src/plugins/devmode.rs @@ -83,7 +83,7 @@ async fn valid_token( .await .unwrap()?; let token = String::from_utf8(data).map_err(|_| Error::IO { - code: std::io::ErrorKind::Other, + code: std::io::ErrorKind::InvalidData, message: format!("Can\'t read dev mode token"), })?; let regex = Regex::new("^[0-9a-zA-Z]+$").unwrap();