2016-03-23 3 views
4

Ich habe ein Problem der Umsetzung des Error Charakterzug. Ich möchte einen Fehler von Diesel oder einem anderen Datenbanktreiber einfügen. Ich habe nicht einmal in der Nähe From zur Umsetzung, da ich bereits Fahren Error Umsetzung. Die Zeile, die dazu führt, dass der Code nicht kompiliert wird, befindet sich am Ende des Codeblocks.Wie implementiert man Fehler :: Ursache richtig?

use std::fmt; 
use std::error::{self, Error}; 

#[derive(Debug)] 
pub enum MyError { 
    NotFound(String), 
    PersistenceError(Box<Error + Send + Sync>), 
} 

pub type MyResult<T> = Result<T, MyError>; 

impl fmt::Display for MyError { 
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 
     match *self { 
      MyError::NotFound(ref msg) => write!(f, "Not found: {}", msg), 
      MyError::PersistenceError(ref cause) => write!(f, "Persistence error: {}", cause), 
     } 
    } 
} 

impl Error for MyError { 
    fn description(&self) -> &str { 
     match *self { 
      MyError::NotFound(ref msg) => msg, 
      MyError::PersistenceError(ref cause) => cause.description(), 
     } 
    } 

    fn cause(&self) -> Option<&Error> { 
     match *self { 
      MyError::NotFound(_) => None, 
      // `*cause` does not live long enough 
      MyError::PersistenceError(cause) => Some(&*cause), 
     } 
    } 
} 

ich auch versucht:

*cause does not live long enough

MyError::PersistenceError(cause) => Some(&*cause), 

the trait core::marker::Sized is not implemented for the type std::error::Error + Send + Sync + 'static [E0277]

MyError::PersistenceError(ref cause) => Some(cause), 

the trait std::error::Error is not implemented for the type `&Box

MyError::PersistenceError(ref cause) => Some(&cause) 

Aber keiner von ihnen arbeitete.

Antwort

6

Es ist nützlich, um print the type of variables in Fällen wie folgt aus:

match *self { 
    MyError::NotFound(_) => None, 
    MyError::PersistenceError(ref cause) => { 
     let() = cause; 
    }, 
} 

Dies wird Ihnen sagen, dass cause ein &Box<std::error::Error + Send + Sync> ist.

Wenn wir es einmal dereferenzieren, haben wir eine Box<std::error::Error + Send + Sync> und wenn wir es ein zweites Mal dereferenzieren, haben wir eine std::error::Error + Send + Sync (das ist kein echter Typ). Wir können dann eine andere Referenz nehmen, die implizit in eine &Error:

match *self { 
    MyError::NotFound(_) => None, 
    MyError::PersistenceError(ref cause) => Some(&**cause), 
} 
gemacht werden kann