Automatically cast errors where possible

This commit is contained in:
timvisee 2018-03-28 19:00:10 +02:00
parent 620e03c6f8
commit ba7d6a6ad1
No known key found for this signature in database
GPG key ID: 109CBA0BF74036C2
7 changed files with 58 additions and 21 deletions

View file

@ -1,16 +1,23 @@
# Ideas # Ideas
- Box errors
- Implement error handling everywhere properly
- `-y` flag for assume yes - `-y` flag for assume yes
- `-f` flag for forcing (no interact?) - `-f` flag for forcing (no interact?)
- Quick upload/download without `upload` or `download` subcommands.
- Set file password - Set file password
- Set file download count. - Set file download count
- Download to a temporary location first
- Soft limit uploads to 1GB and 2GB
- Allow piping input/output files - Allow piping input/output files
- Allow file renaming on upload - Allow file renaming on upload
- Allow file/directory archiving on upload - Allow file/directory archiving on upload
- Allow unarchiving on download - Allow unarchiving on download
- Enter password through pinetry. - Enter password through pinetry
- Remember all uploaded files, make files listable. - Remember all uploaded files, make files listable
- Incognito mode, to not remember files `--incognito`
- Dotfile for default properties - Dotfile for default properties
- Host configuration file for host tags, to easily upload to other hosts. - Host configuration file for host tags, to easily upload to other hosts
- Generate manual pages
- Automated releases through CI - Automated releases through CI
- Release binaries on GitHub - Release binaries on GitHub
- Ubuntu PPA package - Ubuntu PPA package

View file

@ -56,8 +56,7 @@ impl<'a> Download<'a> {
let auth_nonce = self.fetch_auth_nonce(client)?; let auth_nonce = self.fetch_auth_nonce(client)?;
// Fetch the meta nonce, set the input vector // Fetch the meta nonce, set the input vector
let meta_nonce = self.fetch_meta_nonce(&client, &mut key, auth_nonce) let meta_nonce = self.fetch_meta_nonce(&client, &mut key, auth_nonce)?;
.map_err(|err| Error::Request(RequestError::Meta(err)))?;
// Open the file we will write to // Open the file we will write to
// TODO: this should become a temporary file first // TODO: this should become a temporary file first
@ -67,8 +66,7 @@ impl<'a> Download<'a> {
.map_err(|err| Error::File(path.into(), FileError::Create(err)))?; .map_err(|err| Error::File(path.into(), FileError::Create(err)))?;
// Create the file reader for downloading // Create the file reader for downloading
let (reader, len) = self.create_file_reader(&key, meta_nonce, &client) let (reader, len) = self.create_file_reader(&key, meta_nonce, &client)?;
.map_err(|err| Error::Download(err))?;
// Create the file writer // Create the file writer
let writer = self.create_file_writer( let writer = self.create_file_writer(
@ -79,8 +77,7 @@ impl<'a> Download<'a> {
).map_err(|err| Error::File(path.into(), err))?; ).map_err(|err| Error::File(path.into(), err))?;
// Download the file // Download the file
self.download(reader, writer, len, reporter) self.download(reader, writer, len, reporter)?;
.map_err(|err| Error::Download(err))?;
// TODO: return the file path // TODO: return the file path
// TODO: return the new remote state (does it still exist remote) // TODO: return the new remote state (does it still exist remote)
@ -373,6 +370,18 @@ impl From<AuthError> for Error {
} }
} }
impl From<MetaError> for Error {
fn from(err: MetaError) -> Error {
Error::Request(RequestError::Meta(err))
}
}
impl From<DownloadError> for Error {
fn from(err: DownloadError) -> Error {
Error::Download(err)
}
}
#[derive(Fail, Debug)] #[derive(Fail, Debug)]
pub enum RequestError { pub enum RequestError {
/// Failed authenticating, in order to fetch the file data. /// Failed authenticating, in order to fetch the file data.

View file

@ -221,7 +221,6 @@ impl Upload {
}; };
// Transform the responce into a file object // Transform the responce into a file object
// TODO: do some error handling in this into_file method
Ok(response.into_file(self.host.clone(), &key)?) Ok(response.into_file(self.host.clone(), &key)?)
} }
} }
@ -258,8 +257,7 @@ impl UploadResponse {
SendFile::new_now( SendFile::new_now(
self.id, self.id,
host, host,
Url::parse(&self.url) Url::parse(&self.url)?,
.map_err(|err| UploadError::ParseUrl(err))?,
key.secret().to_vec(), key.secret().to_vec(),
self.owner, self.owner,
) )
@ -319,7 +317,7 @@ pub enum Error {
/// An error occurred while opening, reading or using the file that /// An error occurred while opening, reading or using the file that
/// the should be uploaded. /// the should be uploaded.
// TODO: maybe append the file path here for further information // TODO: maybe append the file path here for further information
#[fail(display = "Failed to use the file to upload")] #[fail(display = "")]
File(#[cause] FileError), File(#[cause] FileError),
/// An error occurred while uploading the file. /// An error occurred while uploading the file.
@ -385,7 +383,7 @@ pub enum ReaderError {
#[derive(Fail, Debug)] #[derive(Fail, Debug)]
pub enum FileError { pub enum FileError {
/// The given path, is not not a file or doesn't exist. /// The given path, is not not a file or doesn't exist.
#[fail(display = "The path is not an existing file")] #[fail(display = "The given path is not an existing file")]
NotAFile, NotAFile,
/// Failed to open the file that must be uploaded for reading. /// Failed to open the file that must be uploaded for reading.
@ -417,3 +415,9 @@ pub enum UploadError {
#[fail(display = "Failed to parse received URL")] #[fail(display = "Failed to parse received URL")]
ParseUrl(#[cause] UrlParseError), ParseUrl(#[cause] UrlParseError),
} }
impl From<UrlParseError> for UploadError {
fn from(err: UrlParseError) -> UploadError {
UploadError::ParseUrl(err)
}
}

View file

@ -31,6 +31,7 @@ impl<'a> Download<'a> {
let client = Client::new(); let client = Client::new();
// Parse the file based on the URL // Parse the file based on the URL
// TODO: handle error here
let file = DownloadFile::parse_url(url) let file = DownloadFile::parse_url(url)
.expect("invalid download URL, could not parse file data"); .expect("invalid download URL, could not parse file data");
@ -39,8 +40,7 @@ impl<'a> Download<'a> {
// Execute an download action // Execute an download action
// TODO: do not unwrap, but return an error // TODO: do not unwrap, but return an error
ApiDownload::new(&file).invoke(&client, bar) ApiDownload::new(&file).invoke(&client, bar)?;
.map_err(|err| ActionError::Download(err))?;
// TODO: open the file, or it's location // TODO: open the file, or it's location
// TODO: copy the file location // TODO: copy the file location

View file

@ -39,8 +39,7 @@ impl<'a> Upload<'a> {
let bar = Arc::new(Mutex::new(ProgressBar::new_upload())); let bar = Arc::new(Mutex::new(ProgressBar::new_upload()));
// Execute an upload action // Execute an upload action
let file = ApiUpload::new(host, path).invoke(&client, bar) let file = ApiUpload::new(host, path).invoke(&client, bar)?;
.map_err(|err| ActionError::Upload(err))?;
// Get the download URL, and report it in the console // Get the download URL, and report it in the console
let url = file.download_url(true); let url = file.download_url(true);

View file

@ -8,6 +8,12 @@ pub enum Error {
Action(#[cause] ActionError), Action(#[cause] ActionError),
} }
impl From<ActionError> for Error {
fn from(err: ActionError) -> Error {
Error::Action(err)
}
}
#[derive(Debug, Fail)] #[derive(Debug, Fail)]
pub enum ActionError { pub enum ActionError {
/// An error occurred while invoking the upload action. /// An error occurred while invoking the upload action.
@ -19,3 +25,15 @@ pub enum ActionError {
#[fail(display = "Failed to download the requested file")] #[fail(display = "Failed to download the requested file")]
Download(#[cause] DownloadError), Download(#[cause] DownloadError),
} }
impl From<DownloadError> for ActionError {
fn from(err: DownloadError) -> ActionError {
ActionError::Download(err)
}
}
impl From<UploadError> for ActionError {
fn from(err: UploadError) -> ActionError {
ActionError::Upload(err)
}
}

View file

@ -35,13 +35,13 @@ fn invoke_action(handler: &Handler) -> Result<(), Error> {
// Match the upload command // Match the upload command
if let Some(cmd) = handler.upload() { if let Some(cmd) = handler.upload() {
return Upload::new(&cmd).invoke() return Upload::new(&cmd).invoke()
.map_err(|err| Error::Action(err)); .map_err(|err| err.into());
} }
// Match the download command // Match the download command
if let Some(cmd) = handler.download() { if let Some(cmd) = handler.download() {
return Download::new(&cmd).invoke() return Download::new(&cmd).invoke()
.map_err(|err| Error::Action(err)); .map_err(|err| err.into());
} }
// No subcommand was selected, show general help // No subcommand was selected, show general help