Skip to content

Commit cf1be79

Browse files
committed
perf: Improve error handling for run-time errors
1 parent 542bae4 commit cf1be79

4 files changed

Lines changed: 60 additions & 16 deletions

File tree

src/api.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,13 @@ async fn get_existing(client: &Client, config: &settings::Config) -> Vec<HashMap
193193
fn resolve_payload(body: &[settings::PutItem]) -> Vec<settings::PutItem> {
194194
let mut ret: Vec<settings::PutItem> = Vec::new();
195195
for item in body.iter() {
196-
let url = Url::parse(&item.url).expect("Invalid URL");
196+
let url = match Url::parse(&item.url) {
197+
Ok(url) => url,
198+
Err(e) => {
199+
log::error!("Invalid URL '{}': {}", item.url, e);
200+
return Vec::new();
201+
}
202+
};
197203
let query_pairs: Vec<(String, String)> = url
198204
.query_pairs()
199205
.map(|(key, value)| (key.into_owned(), value.into_owned()))

src/database.rs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ pub fn open() -> Connection {
4545
/// * `entry` - The `RsyncTrack` data to persist.
4646
pub fn upsert(conn: &Connection, hash: &str, entry: &RsyncTrack) {
4747
let (status, progress) = encode_status(&entry.status);
48-
conn.execute(
48+
match conn.execute(
4949
"INSERT OR REPLACE INTO state
5050
(hash, name, status, progress, url, save_path, remote_host, remote_user, remote_path, delete_after_copy)
5151
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)",
@@ -61,8 +61,12 @@ pub fn upsert(conn: &Connection, hash: &str, entry: &RsyncTrack) {
6161
entry.put_item.remote_path,
6262
entry.put_item.delete_after_copy as i32,
6363
],
64-
)
65-
.expect("Failed to upsert state");
64+
) {
65+
Ok(_) => (),
66+
Err(e) => {
67+
log::error!("Failed to upsert state for {}: {}", hash, e);
68+
}
69+
}
6670
}
6771

6872
/// Inserts or replaces a pending transfer entry in the `pending` table.
@@ -73,7 +77,7 @@ pub fn upsert(conn: &Connection, hash: &str, entry: &RsyncTrack) {
7377
/// * `tag` - Unique identifier for the pending item.
7478
/// * `item` - The `PutItem` data to store as pending.
7579
pub fn upsert_pending(conn: &Connection, tag: &str, item: &PutItem) {
76-
conn.execute(
80+
match conn.execute(
7781
"INSERT OR REPLACE INTO pending
7882
(tag, url, save_path, remote_host, remote_user, remote_path, delete_after_copy)
7983
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)",
@@ -86,8 +90,12 @@ pub fn upsert_pending(conn: &Connection, tag: &str, item: &PutItem) {
8690
item.remote_path,
8791
item.delete_after_copy as i32,
8892
],
89-
)
90-
.expect("Failed to upsert pending");
93+
) {
94+
Ok(_) => (),
95+
Err(e) => {
96+
log::error!("Failed to upsert pending for {:?}: {}", item.hash, e);
97+
}
98+
}
9199
}
92100

93101
/// Removes a pending transfer entry by its tag.
@@ -97,8 +105,12 @@ pub fn upsert_pending(conn: &Connection, tag: &str, item: &PutItem) {
97105
/// * `conn` - Active SQLite database connection.
98106
/// * `tag` - Identifier of the pending entry to remove.
99107
pub fn remove_pending(conn: &Connection, tag: &str) {
100-
conn.execute("DELETE FROM pending WHERE tag = ?1", params![tag])
101-
.expect("Failed to remove pending");
108+
match conn.execute("DELETE FROM pending WHERE tag = ?1", params![tag]) {
109+
Ok(_) => (),
110+
Err(e) => {
111+
log::error!("Failed to remove pending for {}: {}", tag, e);
112+
}
113+
}
102114
}
103115

104116
/// Loads all pending transfer entries from the database into memory.
@@ -142,8 +154,12 @@ pub fn load_pending(conn: &Connection) -> HashMap<String, PutItem> {
142154
/// * `conn` - Active SQLite database connection.
143155
/// * `hash` - Unique torrent hash identifier.
144156
pub fn remove(conn: &Connection, hash: &str) {
145-
conn.execute("DELETE FROM state WHERE hash = ?1", params![hash])
146-
.expect("Failed to remove state");
157+
match conn.execute("DELETE FROM state WHERE hash = ?1", params![hash]) {
158+
Ok(_) => (),
159+
Err(e) => {
160+
log::error!("Failed to remove for {}: {}", hash, e);
161+
}
162+
}
147163
}
148164

149165
/// Loads all pending transfer entries from the database into memory.

src/rsync.rs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub async fn run(
6060
put_item.remote_username, put_item.remote_host, put_item.remote_path
6161
);
6262

63-
let mut child = Command::new("rsync")
63+
let child_result = Command::new("rsync")
6464
.args([
6565
"-az",
6666
"--progress",
@@ -70,8 +70,20 @@ pub async fn run(
7070
&remote,
7171
])
7272
.stdout(std::process::Stdio::piped())
73-
.spawn()
74-
.expect("rsync failed");
73+
.stderr(std::process::Stdio::piped())
74+
.spawn();
75+
76+
let mut child = match child_result {
77+
Ok(c) => c,
78+
Err(e) => {
79+
log::error!("Failed to start rsync for {}: {}", name, e);
80+
let mut db = state.write().await;
81+
if let Some(entry) = db.get_mut(&hash) {
82+
entry.status = settings::Status::Failed;
83+
}
84+
return;
85+
}
86+
};
7587

7688
let stdout = child.stdout.take().unwrap();
7789
let mut lines = BufReader::new(stdout).lines();
@@ -87,7 +99,17 @@ pub async fn run(
8799
}
88100
}
89101

90-
let status = child.wait().await.expect("failed to wait on rsync");
102+
let status = match child.wait().await {
103+
Ok(status) => status,
104+
Err(e) => {
105+
log::error!("Failed waiting for rsync process for {}: {}", name, e);
106+
let mut db = state.write().await;
107+
if let Some(entry) = db.get_mut(&hash) {
108+
entry.status = settings::Status::Failed;
109+
}
110+
return;
111+
}
112+
};
91113

92114
if status.success() {
93115
log::info!("rsync complete: {}", name);

src/settings.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use crate::squire;
22
use std::collections::HashMap;
33
use std::num::NonZeroUsize;
4+
use std::str::FromStr;
45
use std::sync::Arc;
56
use tokio::sync::RwLock;
67
use utoipa::ToSchema;
7-
use std::str::FromStr;
88

99
/// ### SharedState
1010
/// Shared application state for tracking active rsync operations.

0 commit comments

Comments
 (0)