2015-04-30 13 views
9

Fondamentalmente, voglio usare il mio tipo di errore personalizzato in tutte le funzioni e ho bisogno di avvolgere gli errori std esistenti in modo che la macro try! abbia successo in tutti i metodi standard.Come implementare un wrapper degli errori per tutti gli errori esistenti

Ecco quello che sto facendo:

#![feature(optin_builtin_traits)] 
use std::error::Error; 
use std::fmt; 
use std::fs; 
#[derive(Debug)] 
enum MyError { 
    A, 
    B, 
} 

impl fmt::Display for MyError { 
    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { 
     Ok(()) 
    } 
} 

impl Error for MyError { 
    fn description(&self) -> &str { 
     "" 
    } 
} 

trait NotMyError { } 
impl NotMyError for .. { } 
impl !NotMyError for MyError { } 

impl<T: NotMyError + Error> From<T> for MyError { 
    fn from(_: T) -> MyError { 
     MyError::A 
    } 
} 

fn test() -> Result<(), MyError> { 
    try!(fs::read_dir("test")); 
    Ok(()) 
} 

fn main() {} 

Il compilatore si lamenta:

<std macros>:6:1: 6:32 error: the trait `NotMyError` is not implemented for the type `std::error::Error + Send + Sync` [E0277] 
<std macros>:6 $ crate:: convert:: From:: from (err)) } }) 
<std macros>:1:1: 6:48 note: in expansion of try! 

Qualsiasi aiuto è molto apprezzato.

+0

Questo mi sembra un insetto. Non riesco a vedere dove il tipo non dimensionato 'std :: error :: Error + Send + Sync' (che probabilmente non implementa' Error', quindi quella parte è vera) arriva -la 'T' in' From l'implementazione è 'std :: io :: errore :: errore'. 'std :: io :: error :: Error' * contiene * un box' Error + Send + Sync', ma questo non dovrebbe avere alcun impatto qui. –

+0

Jon Reem mi ha aiutato a spiegarlo, quindi era chiaro per me: questi elementi negativi sono legati ai tratti dei marcatori come "Invia" e "Sincronizzazione" e quindi interagiscono male con gli oggetti tratti; il tipo 'std :: error :: Error', ad esempio, non implementa' Send', mentre 'std :: error :: Error + Send' fa. L'utilizzo dell'approccio delle implementazioni negative significa che qualsiasi cosa che contiene un oggetto tratto che non ha il collegamento 'NotMyError' aggiunto (ad esempio' std :: error :: Error + Send + Sync + NotMyError') non implementa 'NotMyError'. Mi dispiace, questo approccio che ti ho dato in precedenza sembra che non funzionerà. –

risposta

2

C'è un ottimo post a riguardo:

http://blog.burntsushi.net/rust-error-handling/

per ottenere il supporto di prima classe per il vostro errore è necessario fare due cose:

  • Implementare the Error trait per il vostro tipo
  • Implementare std::convert::From per i tipi di errore che si desidera utilizzare senza problemi nella macro try!.
Problemi correlati