nanalogue_core/
error.rs

1//! # Error
2//!
3//! Covers all errors in our module. These errors arise from us processing
4//! and calculating data associated with DNA molecules, their alignments to
5//! reference genomes, modification information on them, and other miscellaneous
6//! information. We convert errors from other packages to this error type so that
7//! error handling in our package becomes easier.
8
9use crate::F32Bw0and1;
10use derive_builder::UninitializedFieldError;
11use std::char::TryFromCharError;
12use std::fmt;
13use std::io;
14use std::num::{ParseFloatError, ParseIntError, TryFromIntError};
15use std::str::Utf8Error;
16use std::string::FromUtf8Error;
17use thiserror::Error;
18
19/// Enum that covers errors in our module.
20///
21/// Any error arising from our crate does not have the
22/// suffix 'Error'. If we are deriving an error from
23/// an error from another crate, and that has a suffix
24/// 'Error', we have let it be in our naming of the error.
25#[derive(Debug, Error)]
26#[non_exhaustive]
27pub enum Error {
28    /// Alignment of sequence is not known
29    #[error("unknown alignment state: `{0}`")]
30    UnknownAlignState(String),
31
32    /// Failure upon extracting sequence length
33    #[error("invalid sequence length: `{0}`")]
34    InvalidSeqLength(String),
35
36    /// Failure upon extracting or calculating alignment length of molecule
37    #[error("invalid alignment length: `{0}`")]
38    InvalidAlignLength(String),
39
40    /// Contig and start of alignment of molecule are invalid
41    #[error("invalid contig and/or start: `{0}`")]
42    InvalidContigAndStart(String),
43
44    /// Alignment coordinates (contig/start/end) are invalid.
45    #[error(
46        "invalid alignment coordinates (contig/start/end): `{0}`. \n\
47 In command line tool, you can use `nanalogue peek` to check contig names and contig lengths. \n\
48 In command line tool, if piping in a samtools view command, please include header with -h in samtools. "
49    )]
50    InvalidAlignCoords(String),
51
52    /// Modification coordinates are invalid
53    #[error("invalid mod coordinates: `{0}`")]
54    InvalidModCoords(String),
55
56    /// Modification probabilities are invalid
57    #[error("invalid mod probabilities: `{0}`")]
58    InvalidModProbs(String),
59
60    /// Sequence is invalid
61    #[error("invalid sequence: `{0}`")]
62    InvalidSeq(String),
63
64    /// Base is invalid (not A, G, C, T, or N)
65    #[error("invalid base: `{0}`")]
66    InvalidBase(String),
67
68    /// Read id of molecule is invalid
69    #[error("invalid read id: `{0}`")]
70    InvalidReadID(String),
71
72    /// Modification type is invalid. Mod types are indicated in
73    /// mod BAM files like so: ...C+m... where C is the base and
74    /// m is the modification type, in this case methylation.
75    #[error("invalid mod type: `{0}`")]
76    InvalidModType(String),
77
78    /// Modification type is empty
79    #[error("empty mod type: `{0}`")]
80    EmptyModType(String),
81
82    /// Some error from the rust htslib library we use to read BAM files
83    #[error(
84        "rust_htslib error: `{0}` \n\
85 In command line tool, you can use `nanalogue peek` to check contig names and contig lengths. \n\
86 In command line tool, if piping in a samtools view command, please include header with -h in samtools. "
87    )]
88    RustHtslibError(#[from] rust_htslib::errors::Error),
89
90    /// Error upon conversion from integer
91    #[error("integer conversion error: `{0}`")]
92    IntConversionError(#[from] TryFromIntError),
93
94    /// Error involving string conversion
95    #[error("error involving string conversion: `{0}`")]
96    StringConversionError(#[from] Utf8Error),
97
98    /// Error converting from UTF-8 bytes to string
99    #[error("UTF-8 conversion error: `{0}`")]
100    Utf8ConversionError(#[from] FromUtf8Error),
101
102    /// Error parsing JSON
103    #[error("JSON parsing error: `{0}`")]
104    JsonParseError(#[from] serde_json::Error),
105
106    /// `OrdPair` is an ordered pair, which can be obtained from
107    /// a string of the correct format. This error says string
108    /// conversion failed.
109    #[error("ordered pair conversion error: `{0}`")]
110    OrdPairConversion(String),
111
112    /// Problem parsing integers
113    #[error("integer parsing error: `{0}`")]
114    IntParseError(#[from] ParseIntError),
115
116    /// Problem parsing floats
117    #[error("float parsing error: `{0}`")]
118    FloatParseError(#[from] ParseFloatError),
119
120    /// Generic Input-Output error
121    #[error("input output error: `{0}`")]
122    InputOutputError(#[from] io::Error),
123
124    /// Generic formatting error
125    #[error("formatting error: `{0}`")]
126    FormattingError(#[from] fmt::Error),
127
128    /// Problem reading or parsing CSV files
129    #[error("error parsing csv: `{0}`")]
130    CsvError(#[from] csv::Error),
131
132    /// Error when unexpected duplicates are seen
133    #[error("duplicates detected: `{0}`")]
134    InvalidDuplicates(String),
135
136    /// Generic error used when program hits an invalid state
137    #[error("`{0}`")]
138    InvalidState(String),
139
140    /// Error while writing output
141    #[error("error while writing output: `{0}`")]
142    WriteOutput(String),
143
144    /// Generic not implemented error
145    #[error("not implemented: `{0}`")]
146    NotImplemented(String),
147
148    /// General error when ordering of items in some context is wrong.
149    #[error("items in wrong order: `{0}`")]
150    WrongOrder(String),
151
152    /// Data not available
153    #[error("data not available: `{0}`")]
154    UnavailableData(String),
155
156    /// Read is unmapped, use this whenever some function
157    /// meant for a mapped read is called on an unmapped read
158    #[error("read is unmapped: `{0}`")]
159    Unmapped(String),
160
161    /// Zero values used where they should not be
162    #[error("zero values not allowed: `{0}`")]
163    Zero(String),
164
165    /// Zero sequence length
166    #[error("zero sequence length: `{0}`")]
167    ZeroSeqLen(String),
168
169    /// Genomic region coordinates exceed contig boundaries
170    #[error(
171        "invalid region '{region}': position {pos} exceeds contig length {contig_length}\n\
172 In command line tool, you can use `nanalogue peek` to check contig names and contig lengths."
173    )]
174    InvalidRegion {
175        /// The original region string provided by the user
176        region: String,
177        /// The position that exceeds the contig boundary
178        pos: u64,
179        /// The actual length of the contig
180        contig_length: u64,
181    },
182
183    /// Sorting validation failure
184    #[error("invalid sorting: {0}")]
185    InvalidSorting(String),
186
187    /// Window density is below threshold
188    #[error("window density {density} below threshold {threshold}")]
189    WindowDensBelowThres {
190        /// The density value that was below threshold
191        density: F32Bw0and1,
192        /// The threshold value
193        threshold: F32Bw0and1,
194    },
195
196    /// Window does not contain any data
197    #[error("window does not contain any data: `{0}`")]
198    EmptyWindow(String),
199
200    /// Data is not of sufficient size (e.g. in a window)
201    #[error("data is not of sufficient size (e.g. in a window): `{0}`")]
202    InsufficientDataSize(String),
203
204    /// Arithmetic error
205    #[error("unanticipated arithmetic error e.g. overflow: `{0}`")]
206    Arithmetic(String),
207
208    /// Problem parsing items while building structs with Builder methods
209    #[error("building error, are you missing inputs?: `{0}`")]
210    BuilderError(#[from] UninitializedFieldError),
211
212    /// Problem validating items with a Builder method
213    #[error("building error, input validation failed: `{0}`")]
214    BuilderValidation(String),
215
216    /// Problem parsing items while converting between DNA base representations
217    #[error("error converting between DNA bases: `{0}`")]
218    FromCharError(#[from] TryFromCharError),
219
220    /// Error from Polars during `DataFrame` construction or manipulation
221    #[error("Polars error: `{0}`")]
222    PolarsError(#[from] polars::error::PolarsError),
223
224    /// Error simulating DNA sequences
225    #[error("Simulate DNA sequence error; problem at end of CIGAR: {0}")]
226    SimulateDNASeqCIGAREndProblem(String),
227}