1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use failure::Fail;

#[derive(Debug, Fail)]
pub enum SourmashError {
    /// Raised for internal errors in the libraries.  Should not happen.
    #[fail(display = "internal error: {}", message)]
    Internal { message: String },

    #[fail(display = "must have same num: {} != {}", n1, n2)]
    MismatchNum { n1: u32, n2: u32 },

    #[fail(display = "different ksizes cannot be compared")]
    MismatchKSizes,

    #[fail(display = "DNA/prot minhashes cannot be compared")]
    MismatchDNAProt,

    #[fail(display = "mismatch in scaled; comparison fail")]
    MismatchScaled,

    #[fail(display = "mismatch in seed; comparison fail")]
    MismatchSeed,

    #[fail(display = "different signatures cannot be compared")]
    MismatchSignatureType,

    #[fail(display = "Invalid hash function: {}", function)]
    InvalidHashFunction { function: String },

    #[fail(display = "Can only set {} if the MinHash is empty", message)]
    NonEmptyMinHash { message: String },

    #[fail(display = "invalid DNA character in input k-mer: {}", message)]
    InvalidDNA { message: String },

    #[fail(display = "invalid protein character in input: {}", message)]
    InvalidProt { message: String },

    #[fail(display = "Codon is invalid length: {}", message)]
    InvalidCodonLength { message: String },

    #[fail(display = "Error from deserialization")]
    SerdeError,

    #[fail(display = "I/O Error")]
    IOError,
}

#[repr(u32)]
pub enum SourmashErrorCode {
    // no error
    NoError = 0,
    // panics and internals
    Panic = 1,
    Internal = 2,
    Msg = 3,
    Unknown = 4,
    // Compatibility errors
    MismatchKSizes = 1_01,
    MismatchDNAProt = 1_02,
    MismatchScaled = 1_03,
    MismatchSeed = 1_04,
    MismatchSignatureType = 1_05,
    NonEmptyMinHash = 1_06,
    MismatchNum = 1_07,
    // Input sequence errors
    InvalidDNA = 11_01,
    InvalidProt = 11_02,
    InvalidCodonLength = 11_03,
    InvalidHashFunction = 11_04,
    // external errors
    Io = 100_001,
    Utf8Error = 100_002,
    ParseInt = 100_003,
    SerdeError = 100_004,
}

#[cfg(not(all(target_arch = "wasm32", target_vendor = "unknown")))]
impl SourmashErrorCode {
    pub fn from_error(error: &failure::Error) -> SourmashErrorCode {
        for cause in error.iter_chain() {
            use crate::ffi::utils::Panic;
            if cause.downcast_ref::<Panic>().is_some() {
                return SourmashErrorCode::Panic;
            }

            if let Some(err) = cause.downcast_ref::<SourmashError>() {
                return match err {
                    SourmashError::Internal { .. } => SourmashErrorCode::Internal,
                    SourmashError::MismatchNum { .. } => SourmashErrorCode::MismatchNum,
                    SourmashError::MismatchKSizes => SourmashErrorCode::MismatchKSizes,
                    SourmashError::MismatchDNAProt => SourmashErrorCode::MismatchDNAProt,
                    SourmashError::MismatchScaled => SourmashErrorCode::MismatchScaled,
                    SourmashError::MismatchSeed => SourmashErrorCode::MismatchSeed,
                    SourmashError::MismatchSignatureType => {
                        SourmashErrorCode::MismatchSignatureType
                    }
                    SourmashError::NonEmptyMinHash { .. } => SourmashErrorCode::NonEmptyMinHash,
                    SourmashError::InvalidDNA { .. } => SourmashErrorCode::InvalidDNA,
                    SourmashError::InvalidProt { .. } => SourmashErrorCode::InvalidProt,
                    SourmashError::InvalidCodonLength { .. } => {
                        SourmashErrorCode::InvalidCodonLength
                    }
                    SourmashError::InvalidHashFunction { .. } => {
                        SourmashErrorCode::InvalidHashFunction
                    }
                    SourmashError::SerdeError => SourmashErrorCode::SerdeError,
                    SourmashError::IOError => SourmashErrorCode::Io,
                };
            }
        }
        SourmashErrorCode::Unknown
    }
}