Skip to content

Commit 0d48b11

Browse files
authored
Generic errors for entire crate (#249)
* Extract the faidx errors into a global error type * Rename error.rs to errors.rs * Apply renaming of errors to faidx * Move tbx/errors into crate-wide errors * Move bam/errors to crate-wide errors * Move bcf/errors into crate-wide errors * Move SetThreads error into generic error block * Rename Seek/BcfSeek * Move the ThreadPool error into general error section * Remove obsolete bam/errors
1 parent fa07d5e commit 0d48b11

22 files changed

+216
-292
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
44

55
## [next]
66
- BREAKING: Rename feature 'serde' as 'serde_feature' (for technical reasons)
7+
- BREAKING: Consolidate module-wide errors into a crate-wide error module
78

89
## [0.32.0] - 2020-07-09
910
### Changes

src/bam/buffer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ use std::rc::Rc;
88
use std::str;
99

1010
use crate::bam;
11-
use crate::bam::errors::{Error, Result};
1211
use crate::bam::Read;
12+
use crate::errors::{Error, Result};
1313

1414
/// A buffer for BAM records. This allows access regions in a sorted BAM file while iterating
1515
/// over it in a single pass.

src/bam/errors.rs

Lines changed: 0 additions & 51 deletions
This file was deleted.

src/bam/index.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use std::path::Path;
99
use std::ptr;
1010

11-
use crate::bam::errors::{Error, Result};
11+
use crate::errors::{Error, Result};
1212
use crate::htslib;
1313
use crate::utils;
1414

@@ -49,12 +49,12 @@ pub fn build<P: AsRef<Path>>(
4949
};
5050
match ret {
5151
0 => Ok(()),
52-
-1 => Err(Error::BuildIndex),
53-
-2 => Err(Error::Open {
52+
-1 => Err(Error::BamBuildIndex),
53+
-2 => Err(Error::BamOpen {
5454
target: bam_path.as_ref().to_str().unwrap().to_owned(),
5555
}),
56-
-3 => Err(Error::NotIndexable),
57-
-4 => Err(Error::WriteIndex),
56+
-3 => Err(Error::BamNotIndexable),
57+
-4 => Err(Error::BamWriteIndex),
5858
e => panic!("unexpected error code from sam_index_build3: {}", e),
5959
}
6060
}

src/bam/mod.rs

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
//! Module for working with SAM, BAM, and CRAM files.
77
88
pub mod buffer;
9-
pub mod errors;
109
pub mod ext;
1110
pub mod header;
1211
pub mod index;
@@ -24,11 +23,12 @@ use std::str;
2423

2524
use url::Url;
2625

26+
use crate::errors::{Error, Result};
2727
use crate::htslib;
2828
use crate::tpool::ThreadPool;
29+
use crate::utils::path_as_bytes;
2930

3031
pub use crate::bam::buffer::RecordBuffer;
31-
pub use crate::bam::errors::{Error, Result};
3232
pub use crate::bam::header::Header;
3333
pub use crate::bam::record::Record;
3434
use std::convert::TryInto;
@@ -75,7 +75,7 @@ pub unsafe fn set_fai_filename<P: AsRef<Path>>(
7575
if htslib::hts_set_fai_filename(htsfile, c_str.as_ptr()) == 0 {
7676
Ok(())
7777
} else {
78-
Err(Error::InvalidReferencePath { path: p.to_owned() })
78+
Err(Error::BamInvalidReferencePath { path: p.to_owned() })
7979
}
8080
}
8181

@@ -95,7 +95,8 @@ pub trait Read: Sized {
9595
///
9696
/// Example:
9797
/// ```
98-
/// use rust_htslib::bam::{Error, Read, IndexedReader, Record};
98+
/// use rust_htslib::errors::Error;
99+
/// use rust_htslib::bam::{Read, IndexedReader, Record};
99100
///
100101
/// let mut bam = IndexedReader::from_path(&"test/test.bam").unwrap();
101102
/// bam.fetch((0, 1000, 2000)); // reads on tid 0, from 1000bp to 2000bp
@@ -130,7 +131,8 @@ pub trait Read: Sized {
130131
///
131132
/// Example:
132133
/// ```
133-
/// use rust_htslib::bam::{Error, Read, Reader, Record};
134+
/// use rust_htslib::errors::Error;
135+
/// use rust_htslib::bam::{Read, Reader, Record};
134136
/// use rust_htslib::htslib; // for BAM_F*
135137
/// let mut bam = Reader::from_path(&"test/test.bam").unwrap();
136138
///
@@ -182,7 +184,7 @@ pub trait Read: Sized {
182184
if ret == 0 {
183185
Ok(())
184186
} else {
185-
Err(Error::Seek)
187+
Err(Error::FileSeek)
186188
}
187189
}
188190

@@ -217,21 +219,6 @@ pub trait Read: Sized {
217219
fn set_thread_pool(&mut self, tpool: &ThreadPool) -> Result<()>;
218220
}
219221

220-
fn path_as_bytes<'a, P: 'a + AsRef<Path>>(path: P, must_exist: bool) -> Result<Vec<u8>> {
221-
if path.as_ref().exists() || !must_exist {
222-
Ok(path
223-
.as_ref()
224-
.to_str()
225-
.ok_or(Error::NonUnicodePath)?
226-
.as_bytes()
227-
.to_owned())
228-
} else {
229-
Err(Error::FileNotFound {
230-
path: path.as_ref().to_owned(),
231-
})
232-
}
233-
}
234-
235222
/// A BAM reader.
236223
#[derive(Debug)]
237224
pub struct Reader {
@@ -333,7 +320,8 @@ impl Read for Reader {
333320
/// # Examples
334321
///
335322
/// ```
336-
/// use rust_htslib::bam::{Error, Read, Reader, Record};
323+
/// use rust_htslib::errors::Error;
324+
/// use rust_htslib::bam::{Read, Reader, Record};
337325
///
338326
/// let mut bam = Reader::from_path(&"test/test.bam")?;
339327
/// let mut record = Record::new();
@@ -353,8 +341,8 @@ impl Read for Reader {
353341
)
354342
} {
355343
-1 => Ok(false),
356-
-2 => Err(Error::TruncatedRecord),
357-
-4 => Err(Error::InvalidRecord),
344+
-2 => Err(Error::BamTruncatedRecord),
345+
-4 => Err(Error::BamInvalidRecord),
358346
_ => {
359347
record.set_header(Rc::clone(&self.header));
360348

@@ -602,7 +590,7 @@ impl IndexedReader {
602590
let c_str = ffi::CString::new(path).unwrap();
603591
let idx = unsafe { htslib::sam_index_load(htsfile, c_str.as_ptr()) };
604592
if idx.is_null() {
605-
Err(Error::InvalidIndex {
593+
Err(Error::BamInvalidIndex {
606594
target: str::from_utf8(path).unwrap().to_owned(),
607595
})
608596
} else {
@@ -630,7 +618,7 @@ impl IndexedReader {
630618
htslib::sam_index_load2(htsfile, c_str_path.as_ptr(), c_str_index_path.as_ptr())
631619
};
632620
if idx.is_null() {
633-
Err(Error::InvalidIndex {
621+
Err(Error::BamInvalidIndex {
634622
target: str::from_utf8(path).unwrap().to_owned(),
635623
})
636624
} else {
@@ -791,8 +779,8 @@ impl Read for IndexedReader {
791779
Some(itr) => {
792780
match itr_next(self.htsfile, itr, &mut record.inner as *mut htslib::bam1_t) {
793781
-1 => Ok(false),
794-
-2 => Err(Error::TruncatedRecord),
795-
-4 => Err(Error::InvalidRecord),
782+
-2 => Err(Error::BamTruncatedRecord),
783+
-4 => Err(Error::BamInvalidRecord),
796784
_ => {
797785
record.set_header(Rc::clone(&self.header));
798786

@@ -990,7 +978,7 @@ impl Writer {
990978
/// * `record` - the record to write
991979
pub fn write(&mut self, record: &record::Record) -> Result<()> {
992980
if unsafe { htslib::sam_write1(self.f, self.header.inner(), record.inner_ptr()) } == -1 {
993-
Err(Error::Write)
981+
Err(Error::WriteRecord)
994982
} else {
995983
Ok(())
996984
}
@@ -1025,7 +1013,7 @@ impl Writer {
10251013
)
10261014
} {
10271015
0 => Ok(()),
1028-
_ => Err(Error::InvalidCompressionLevel { level }),
1016+
_ => Err(Error::BamInvalidCompressionLevel { level }),
10291017
}
10301018
}
10311019
}
@@ -1052,7 +1040,7 @@ impl CompressionLevel {
10521040
CompressionLevel::Fastest => Ok(1),
10531041
CompressionLevel::Maximum => Ok(9),
10541042
CompressionLevel::Level(i @ 0..=9) => Ok(i),
1055-
CompressionLevel::Level(i) => Err(Error::InvalidCompressionLevel { level: i }),
1043+
CompressionLevel::Level(i) => Err(Error::BamInvalidCompressionLevel { level: i }),
10561044
}
10571045
}
10581046
}
@@ -1144,7 +1132,7 @@ fn hts_open(path: &[u8], mode: &[u8]) -> Result<*mut htslib::htsFile> {
11441132
let c_str = ffi::CString::new(mode).unwrap();
11451133
let ret = unsafe { htslib::hts_open(cpath.as_ptr(), c_str.as_ptr()) };
11461134
if ret.is_null() {
1147-
Err(Error::Open {
1135+
Err(Error::BamOpen {
11481136
target: path.to_owned(),
11491137
})
11501138
} else {
@@ -1156,7 +1144,7 @@ fn hts_open(path: &[u8], mode: &[u8]) -> Result<*mut htslib::htsFile> {
11561144
&& (*ret).format.format != htslib::htsExactFormat_bam
11571145
&& (*ret).format.format != htslib::htsExactFormat_cram
11581146
{
1159-
return Err(Error::Open {
1147+
return Err(Error::BamOpen {
11601148
target: path.to_owned(),
11611149
});
11621150
}

src/bam/pileup.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ use std::slice;
1010
use crate::htslib;
1111

1212
use crate::bam;
13-
use crate::bam::errors::{Error, Result};
1413
use crate::bam::record;
14+
use crate::errors::{Error, Result};
1515

1616
/// Iterator over alignments of a pileup.
1717
pub type Alignments<'a> = iter::Map<
@@ -162,7 +162,7 @@ impl<'a, R: bam::Read> Iterator for Pileups<'a, R> {
162162
let inner = unsafe { htslib::bam_plp_auto(self.itr, &mut tid, &mut pos, &mut depth) };
163163

164164
match inner.is_null() {
165-
true if depth == -1 => Some(Err(Error::Pileup)),
165+
true if depth == -1 => Some(Err(Error::BamPileup)),
166166
true => None,
167167
false => Some(Ok(Pileup {
168168
inner,

src/bam/record.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,13 @@ use std::u32;
1717
use lazy_static::lazy_static;
1818
use regex::Regex;
1919

20-
#[cfg(feature = "serde_feature")]
21-
use serde::{self, Deserialize, Serialize};
22-
23-
use crate::bam::errors::Result;
2420
use crate::bam::Error;
2521
use crate::bam::HeaderView;
22+
use crate::errors::Result;
2623
use crate::htslib;
2724
use crate::utils;
25+
#[cfg(feature = "serde_feature")]
26+
use serde::{self, Deserialize, Serialize};
2827

2928
use bio_types::alignment::{Alignment, AlignmentMode, AlignmentOperation};
3029
use bio_types::genome;
@@ -166,7 +165,7 @@ impl Record {
166165
if succ == 0 {
167166
Ok(record)
168167
} else {
169-
Err(Error::ParseSAM {
168+
Err(Error::BamParseSAM {
170169
rec: str::from_utf8(&sam_copy).unwrap().to_owned(),
171170
})
172171
}
@@ -1046,7 +1045,7 @@ impl TryFrom<&[u8]> for CigarString {
10461045

10471046
/// Create a CigarString from given bytes.
10481047
fn try_from(text: &[u8]) -> Result<Self> {
1049-
Self::try_from(str::from_utf8(text).map_err(|_| Error::ParseCigar {
1048+
Self::try_from(str::from_utf8(text).map_err(|_| Error::BamParseCigar {
10501049
msg: "unable to parse as UTF8".to_owned(),
10511050
})?)
10521051
}
@@ -1068,7 +1067,7 @@ impl TryFrom<&str> for CigarString {
10681067
let n = &caps["n"];
10691068
let op = &caps["op"];
10701069
i += n.len() + op.len();
1071-
let n = u32::from_str(n).map_err(|_| Error::ParseCigar {
1070+
let n = u32::from_str(n).map_err(|_| Error::BamParseCigar {
10721071
msg: "expected integer".to_owned(),
10731072
})?;
10741073
inner.push(match op {
@@ -1082,13 +1081,13 @@ impl TryFrom<&str> for CigarString {
10821081
"=" => Cigar::Equal(n),
10831082
"X" => Cigar::Diff(n),
10841083
op => {
1085-
return Err(Error::ParseCigar {
1084+
return Err(Error::BamParseCigar {
10861085
msg: format!("operation {} not expected", op),
10871086
});
10881087
}
10891088
});
10901089
} else {
1091-
return Err(Error::ParseCigar {
1090+
return Err(Error::BamParseCigar {
10921091
msg: "expected cigar operation [0-9]+[MIDNSHP=X]".to_owned(),
10931092
});
10941093
}
@@ -1238,17 +1237,17 @@ impl CigarStringView {
12381237
break;
12391238
},
12401239
Cigar::Del(_) => {
1241-
return Err(Error::UnexpectedCigarOperation {
1240+
return Err(Error::BamUnexpectedCigarOperation {
12421241
msg: "'deletion' (D) found before any operation describing read sequence".to_owned()
12431242
});
12441243
},
12451244
Cigar::RefSkip(_) => {
1246-
return Err(Error::UnexpectedCigarOperation {
1245+
return Err(Error::BamUnexpectedCigarOperation {
12471246
msg: "'reference skip' (N) found before any operation describing read sequence".to_owned()
12481247
});
12491248
},
12501249
Cigar::HardClip(_) if i > 0 && i < self.len()-1 => {
1251-
return Err(Error::UnexpectedCigarOperation{
1250+
return Err(Error::BamUnexpectedCigarOperation{
12521251
msg: "'hard clip' (H) found in between operations, contradicting SAMv1 spec that hard clips can only be at the ends of reads".to_owned()
12531252
});
12541253
},
@@ -1305,7 +1304,7 @@ impl CigarStringView {
13051304
j += 1;
13061305
}
13071306
Cigar::HardClip(_) if j < self.len() - 1 => {
1308-
return Err(Error::UnexpectedCigarOperation{
1307+
return Err(Error::BamUnexpectedCigarOperation{
13091308
msg: "'hard clip' (H) found in between operations, contradicting SAMv1 spec that hard clips can only be at the ends of reads".to_owned()
13101309
});
13111310
}

src/bcf/buffer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use std::cmp::Ordering;
77
use std::collections::{vec_deque, VecDeque};
88
use std::mem;
99

10-
use crate::bcf::errors::Result;
1110
use crate::bcf::{self, Read};
11+
use crate::errors::Result;
1212

1313
/// A buffer for BCF records. This allows access regions in a sorted BCF file while iterating
1414
/// over it in a single pass.

0 commit comments

Comments
 (0)