Skip to main content

osv_db/
errors.rs

1use chrono::{DateTime, Utc};
2use thiserror::Error;
3
4/// Error returned by downloader operations (HTTP and I/O).
5#[derive(Debug, Error)]
6pub enum DownloaderErr {
7    /// An HTTP request failed.
8    #[error("HTTP request failed: {0}")]
9    Http(#[source] reqwest::Error),
10    /// A file-system I/O operation failed.
11    #[error("I/O error: {0}")]
12    Io(#[source] std::io::Error),
13}
14
15/// Error returned by `OsvDb::new`.
16#[derive(Debug, Error)]
17pub enum OsvDbNewErr {
18    /// Failed to create or access the database directory.
19    #[error("failed to create or access the database directory: {0}")]
20    Io(#[source] std::io::Error),
21}
22
23/// Error returned by `OsvDb::get_record`.
24#[derive(Debug, Error)]
25pub enum GetRecordErr {
26    /// Failed to open or read the record file.
27    #[error("failed to open or read record file: {0}")]
28    Io(#[source] std::io::Error),
29    /// Failed to deserialize the record JSON.
30    #[error("failed to deserialize OSV record: {0}")]
31    Json(#[source] serde_json::Error),
32}
33
34/// Error returned by `OsvDb::records`.
35#[derive(Debug, Error)]
36pub enum RecordsIterErr {
37    /// Failed to open the records directory for reading.
38    #[error("failed to read the records directory: {0}")]
39    ReadDir(#[source] std::io::Error),
40}
41
42/// Error yielded by individual iterator items from `OsvDb::records` and
43/// `OsvDb::sync`.
44#[derive(Debug, Error)]
45pub enum ReadRecordErr {
46    /// Failed to read the record file from disk.
47    #[error("failed to read record file: {0}")]
48    Io(#[source] std::io::Error),
49    /// Failed to deserialize the record JSON.
50    #[error("failed to deserialize OSV record: {0}")]
51    Json(#[source] serde_json::Error),
52}
53
54/// Error returned by `OsvModifiedRecord::try_from_csv_record`.
55#[derive(Debug, Error)]
56pub enum ParseModifiedRecordErr {
57    /// The CSV row did not have exactly 2 columns.
58    #[error("expected 2 columns, got {0}")]
59    WrongColumnCount(usize),
60    /// The timestamp column (index 0) was absent.
61    #[error("missing timestamp column")]
62    MissingTimestamp,
63    /// The path column (index 1) was absent.
64    #[error("missing path column")]
65    MissingPath,
66    /// The timestamp string could not be parsed as an RFC 3339 date-time.
67    #[error("invalid timestamp: {0}")]
68    ParseTimestamp(#[source] chrono::ParseError),
69    /// The ecosystem string did not match any known variant.
70    #[error("invalid ecosystem: {0}")]
71    ParseEcosystem(#[source] strum::ParseError),
72    /// The path column did not have the expected `<ecosystem>/<id>` format.
73    #[error("invalid path format, expected `<ecosystem>/<id>`, got: `{0}`")]
74    InvalidPathFormat(String),
75}
76
77/// Error returned by `OsvDb::download_latest`.
78#[derive(Debug, Error)]
79pub enum DownloadLatestErr {
80    /// A file-system I/O operation failed.
81    #[error("I/O error: {0}")]
82    Io(#[source] std::io::Error),
83    /// A network download operation failed.
84    #[error("download error: {0}")]
85    Download(#[source] DownloaderErr),
86    /// A ZIP archive operation failed.
87    #[error("ZIP archive error: {0}")]
88    Zip(#[source] zip::result::ZipError),
89    /// A CSV parsing operation failed.
90    #[error("CSV parsing error: {0}")]
91    Csv(#[source] csv::Error),
92    /// A `modified_id.csv` row could not be parsed.
93    #[error("failed to parse modified record: {0}")]
94    ParseRecord(#[source] ParseModifiedRecordErr),
95    /// The `modified_id.csv` file contained no rows.
96    #[error("modified_id.csv contains no entries")]
97    EmptyModifiedCsv,
98    /// The `modified` timestamp cannot be represented as nanoseconds.
99    #[error("timestamp `{0}` is outside the representable nanosecond range")]
100    TimestampOutOfRange(DateTime<Utc>),
101}
102
103/// Error returned by `OsvDb::sync`.
104#[derive(Debug, Error)]
105pub enum SyncErr {
106    /// A file-system I/O operation failed.
107    #[error("I/O error: {0}")]
108    Io(#[source] std::io::Error),
109    /// A network download operation failed.
110    #[error("download error: {0}")]
111    Download(#[source] DownloaderErr),
112    /// A CSV parsing operation failed.
113    #[error("CSV parsing error: {0}")]
114    Csv(#[source] csv::Error),
115    /// A `modified_id.csv` row could not be parsed.
116    #[error("failed to parse modified record: {0}")]
117    ParseRecord(#[source] ParseModifiedRecordErr),
118    /// A spawned background task panicked.
119    #[error("background task panicked: {0}")]
120    Join(#[source] tokio::task::JoinError),
121    /// The `modified` timestamp cannot be represented as nanoseconds.
122    #[error("timestamp `{0}` is outside the representable nanosecond range")]
123    TimestampOutOfRange(DateTime<Utc>),
124}