1 //Copyright 2016 secret-service-rs Developers 2 // 3 // Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or 4 // http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or 5 // http://opensource.org/licenses/MIT>, at your option. This file may not be 6 // copied, modified, or distributed except according to those terms. 7 8 // implement custom errors 9 // 10 // Classes of errors: 11 // - Dbus (IO, validation) 12 // - crypto 13 // - parsing dbus output (dbus returns unrecognizable output). Sometimes it's 14 // for if the index exists in the results vector, sometimes it's for whether 15 // the value being parsed at that index is the right type. Along these lines 16 // I'm currently using unwrap() for converting types, should these also return 17 // Result? 18 // 19 // Almost all custom errors are of this type. It's mostly an internal error, 20 // unexpected behavior indicates something very wrong, so should it panic? Or 21 // is it still better to bubble up? 22 // - locked (currently custom dbus error) 23 // - prompt dismissed (not an error?) (currently custom dbus error) 24 25 use dbus; 26 use std::error; 27 use std::fmt; 28 29 /// Result type often returned from methods that have SsError. 30 /// Fns in this library return ::Result<T> when using this alias. 31 // (This pattern is something I saw in hyper) 32 pub type Result<T> = ::std::result::Result<T, SsError>; 33 34 #[derive(Debug)] 35 pub enum SsError { 36 Crypto(String), 37 Dbus(dbus::Error), 38 Locked, 39 NoResult, 40 Parse, 41 Prompt, 42 } 43 44 impl fmt::Display for SsError { fmt(&self, f: &mut fmt::Formatter) -> fmt:: Result45 fn fmt(&self, f: &mut fmt::Formatter) -> fmt:: Result { 46 match *self { 47 // crypto error does not implement Display 48 SsError::Crypto(_) => write!(f, "Crypto error: Invalid Length or Padding"), 49 SsError::Dbus(ref err) => write!(f, "Dbus error: {}", err), 50 SsError::Locked => write!(f, "SS Error: object locked"), 51 SsError::NoResult => write!(f, "SS error: result not returned from SS API"), 52 SsError::Parse => write!(f, "SS error: could not parse Dbus output"), 53 SsError::Prompt => write!(f, "SS error: prompt dismissed"), 54 } 55 } 56 } 57 58 impl error::Error for SsError { description(&self) -> &str59 fn description(&self) -> &str { 60 match *self { 61 SsError::Crypto(_) => "crypto: Invalid Length or Padding", 62 SsError::Dbus(ref err) => err.description(), 63 SsError::Locked => "Object locked", 64 SsError::NoResult => "Result not returned from SS API", 65 SsError::Parse => "Error parsing Dbus output", 66 SsError::Prompt => "Prompt Dismissed", 67 } 68 } 69 cause(&self) -> Option<&error::Error>70 fn cause(&self) -> Option<&error::Error> { 71 match *self { 72 SsError::Dbus(ref err) => Some(err), 73 _ => None, 74 } 75 } 76 } 77 78 impl From<block_modes::BlockModeError> for SsError { from(_err: block_modes::BlockModeError) -> SsError79 fn from(_err: block_modes::BlockModeError) -> SsError { 80 SsError::Crypto("Block mode error".into()) 81 } 82 } 83 84 impl From<block_modes::InvalidKeyIvLength> for SsError { from(_err: block_modes::InvalidKeyIvLength) -> SsError85 fn from(_err: block_modes::InvalidKeyIvLength) -> SsError { 86 SsError::Crypto("Invalid Key Iv Lengt".into()) 87 } 88 } 89 90 impl From<dbus::Error> for SsError { from(err: dbus::Error) -> SsError91 fn from(err: dbus::Error) -> SsError { 92 SsError::Dbus(err) 93 } 94 } 95 96