Skip to content

Commit

Permalink
Improve custom error structure for better messages
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanfrishkorn committed Aug 31, 2023
1 parent ccfa555 commit 4278a4e
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 81 deletions.
40 changes: 12 additions & 28 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,17 @@ fn main() -> Result<(), Box<dyn Error>> {
.ok_or("uuid not present")?;

// search for unique uuid to allow partial string arg
let id = snip::search_uuid(&conn, id_str)?;
let id = match snip::search_uuid(&conn, id_str) {
Ok(v) => v,
Err(e) => {
match &e {
SnipError::UuidNotFound(s) => println!("{}", s),
SnipError::UuidMultipleMatches(s) => println!("{}", s),
_ => return Err(Box::new(e)),
}
return Ok(());
}
};
let mut s = snip::get_from_uuid(&conn, &id)?;

// check for raw or formatted output
Expand All @@ -466,33 +476,7 @@ fn main() -> Result<(), Box<dyn Error>> {
false => {
s.collect_attachments(&conn)?;
s.print();
} /*
false => {
println!(
"uuid: {}\nname: {}\ntimestamp: {}\n----",
s.uuid,
s.name,
s.timestamp.to_rfc3339()
);
// add a newline if not already present
match s.text.chars().last() {
Some(v) if v == '\n' => println!("{}----", s.text),
_ => println!("{}\n----", s.text),
}
// show attachments
s.collect_attachments(&conn)?;
if !s.attachments.is_empty() {
println!("attachments:");
println!("{:<36} {:>10} name", "uuid", "bytes");
for a in &s.attachments {
println!("{} {:>10} {}", a.uuid, a.size, a.name);
}
}
}
*/
}
}
}

Expand Down
69 changes: 27 additions & 42 deletions src/snip/error.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use std::error::Error;
use std::fmt;

/// Errors for Snip Analysis
/// Custom Errors
pub enum SnipError {
Analysis(String),
General(String),
UuidMultipleMatches(String),
SearchNoMatches(String),
UuidMultipleMatches(String),
UuidNotFound(String),
}

Expand All @@ -15,53 +15,38 @@ impl Error for SnipError {}
impl fmt::Display for SnipError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
SnipError::Analysis(s) => write!(f, "Analysis encountered an error: {}", s),
SnipError::General(s) => write!(f, "{}", s),
SnipError::UuidMultipleMatches(s) => write!(f, "{}", s),
SnipError::SearchNoMatches(s) => write!(f, "{}", s),
SnipError::UuidNotFound(s) => write!(f, "uuid {} was not found", s),
SnipError::Analysis(s) => write!(f, "{:?}: {}", self, s),
SnipError::General(s) => write!(f, "{:?}: {}", self, s),
SnipError::SearchNoMatches(s) => write!(f, "{:?}: {}", self, s),
SnipError::UuidMultipleMatches(s) => write!(f, "{:?}: {}", self, s),
SnipError::UuidNotFound(s) => write!(f, "The id requested was not found: {}", s),
}
}
}

impl fmt::Debug for SnipError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
SnipError::Analysis(s) => write!(
f,
"{{ SnipError::Analysis({}) file: {}, line: {} }}",
s,
file!(),
line!()
),
SnipError::General(s) => write!(
f,
"{{ SnipError::General({}) file: {}, line: {} }}",
s,
file!(),
line!()
),
SnipError::UuidMultipleMatches(s) => write!(
f,
"{{ SnipError::UuidMultipleMatches({}) file: {}, line: {} }}",
s,
file!(),
line!()
),
SnipError::SearchNoMatches(s) => write!(
f,
"{{ SnipError::NoIndexMatches({}) file: {}, line: {} }}",
s,
file!(),
line!()
),
SnipError::UuidNotFound(s) => write!(
f,
"{{ SnipError::UuidNotFound({}) file: {}, line: {} }}",
s,
file!(),
line!()
),
SnipError::Analysis(s) => f
.debug_struct("SnipError::Analysis")
.field("msg", s)
.finish(),
SnipError::General(s) => f
.debug_struct("SnipError::General")
.field("msg", s)
.finish(),
SnipError::SearchNoMatches(s) => f
.debug_struct("SnipError::SearchNoMatches")
.field("msg", s)
.finish(),
SnipError::UuidMultipleMatches(s) => f
.debug_struct("SnipError::UuidMultipleMatches")
.field("msg", s)
.finish(),
SnipError::UuidNotFound(s) => f
.debug_struct("SnipError::UuidNotFound")
.field("msg", s)
.finish(),
}
}
}
34 changes: 23 additions & 11 deletions src/snip/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,38 +252,50 @@ pub fn search_all_present(

/// Search for a uuid matching the supplied partial string.
/// The partial uuid must match a unique record to return the result.
pub fn search_uuid(conn: &Connection, id_partial: &str) -> Result<Uuid, Box<dyn Error>> {
let mut stmt = conn.prepare("SELECT uuid from snip WHERE uuid LIKE :id LIMIT 2")?;
pub fn search_uuid(conn: &Connection, id_partial: &str) -> Result<Uuid, SnipError> {
let mut stmt = match conn.prepare("SELECT uuid from snip WHERE uuid LIKE :id LIMIT 2") {
Ok(v) => v,
Err(e) => {
println!("There was a problem preparing the search query: {}", e);
return Err(SnipError::General(format!("{}", e)));
}
};
let id_partial_fuzzy = format!("{}{}{}", "%", id_partial, "%");

let rows = stmt.query_map(&[(":id", &id_partial_fuzzy)], |row| {
let id_str = row.get(0)?;
let rows = match stmt.query_map(&[(":id", &id_partial_fuzzy)], |row| {
let id_str = match row.get(0) {
Ok(v) => v,
Err(e) => return Err(e),
};
Ok(id_str)
})?;
}) {
Ok(v) => v,
Err(e) => return Err(SnipError::General(format!("{}", e))),
};

// return only if a singular result is matched, so we check for two results
let mut id_str = String::new();
for (i, id) in rows.into_iter().enumerate() {
if i == 0 {
id_str = id.unwrap();
} else {
return Err(Box::new(SnipError::UuidMultipleMatches(format!(
return Err(SnipError::UuidMultipleMatches(format!(
"provided partial {} returned multiple document uuids",
id_partial
))));
)));
}
}

if !id_str.is_empty() {
return match Uuid::parse_str(&id_str) {
Ok(v) => Ok(v),
Err(e) => Err(Box::new(e)),
Err(e) => Err(SnipError::General(format!("{}", e))),
};
}
Err(Box::new(SnipError::UuidNotFound(format!(
"document uuid not found using partial {}",
Err(SnipError::UuidNotFound(format!(
"The document id was not found using id {}",
id_partial
))))
)))
}

#[cfg(test)]
Expand Down

0 comments on commit 4278a4e

Please sign in to comment.