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