Skip to content

Commit 962da88

Browse files
hyperpolymathclaude
andcommitted
Revert 43 .expect("TODO: handle error") sites across 4 files (batch 2/N)
Continues the per-site reversal of the .unwrap() → .expect("TODO: handle error") anti-pattern flagged by CRG-AUDIT-2026-04-18. Per-site policy: * Test code → revert to .unwrap() (test convention; preceding asserts or short-circuits already prove the Some/Ok case). Files this batch: - process_sub.rs (11 sites in tests::test_fifo_*) - audit_log.rs (13 sites in tests::test_audit_*) - job.rs ( 7 sites in tests::test_get_job_*, test_remove_job) - functions.rs (11 sites in tests::test_parse_function_*, test_function_table_*, test_pop_frame_*) * Production code, functions.rs:320 — restructure `if name.is_empty() { return false; } let mut chars = name.chars(); let first = chars.next().expect("TODO: handle error");` to `let mut chars = name.chars(); let Some(first) = chars.next() else { return false; };` chars.next() returns None on an empty &str, so the let-else covers the empty-name case directly. One construct, no panic site, identical behaviour. Verified by the existing is_valid_function_name tests. Verified locally: cargo build -> EXIT 0 cargo test -> 703 passed / 0 failed / 14 ignored (unchanged from batch 1; restructure preserves behaviour exactly) Cumulative progress: 57 / ~530 sites cleared (~11%). Remaining: 17 files, biggest are parser.rs (116), commands.rs (66), arith.rs (55), state.rs (35). Plus the impl/rust-ffi/ ↔ ffi/rust/ duplicate tree (~50 more, separate finding). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 712e3a1 commit 962da88

4 files changed

Lines changed: 48 additions & 46 deletions

File tree

impl/rust-cli/src/audit_log.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -284,55 +284,55 @@ mod tests {
284284
let op = Operation::new(OperationType::Mkdir, "test_dir".to_string(), None);
285285
let entry = AuditEntry::from_operation(&op, "success", None);
286286

287-
let json_line = entry.to_json_line().expect("TODO: handle error");
287+
let json_line = entry.to_json_line().unwrap();
288288
assert!(json_line.ends_with('\n'));
289289

290-
let parsed = AuditEntry::from_json_line(&json_line).expect("TODO: handle error");
290+
let parsed = AuditEntry::from_json_line(&json_line).unwrap();
291291
assert_eq!(parsed.operation_id, entry.operation_id);
292292
assert_eq!(parsed.path, "test_dir");
293293
assert_eq!(parsed.outcome, "success");
294294
}
295295

296296
#[test]
297297
fn test_audit_log_append_and_read() {
298-
let temp_file = NamedTempFile::new().expect("TODO: handle error");
298+
let temp_file = NamedTempFile::new().unwrap();
299299
let log_path = temp_file.path().to_path_buf();
300300

301-
let log = AuditLog::new(log_path, None).expect("TODO: handle error");
301+
let log = AuditLog::new(log_path, None).unwrap();
302302

303303
// Append some entries
304304
let op1 = Operation::new(OperationType::Mkdir, "dir1".to_string(), None);
305305
let entry1 = AuditEntry::from_operation(&op1, "success", None);
306-
log.append(&entry1).expect("TODO: handle error");
306+
log.append(&entry1).unwrap();
307307

308308
let op2 = Operation::new(OperationType::CreateFile, "file1".to_string(), None);
309309
let entry2 = AuditEntry::from_operation(&op2, "success", None);
310-
log.append(&entry2).expect("TODO: handle error");
310+
log.append(&entry2).unwrap();
311311

312312
// Read back
313-
let entries = log.read_all().expect("TODO: handle error");
313+
let entries = log.read_all().unwrap();
314314
assert_eq!(entries.len(), 2);
315315
assert_eq!(entries[0].path, "dir1");
316316
assert_eq!(entries[1].path, "file1");
317317
}
318318

319319
#[test]
320320
fn test_audit_log_filter_by_type() {
321-
let temp_file = NamedTempFile::new().expect("TODO: handle error");
321+
let temp_file = NamedTempFile::new().unwrap();
322322
let log_path = temp_file.path().to_path_buf();
323323

324-
let log = AuditLog::new(log_path, None).expect("TODO: handle error");
324+
let log = AuditLog::new(log_path, None).unwrap();
325325

326326
let op1 = Operation::new(OperationType::Mkdir, "dir1".to_string(), None);
327-
log.append(&AuditEntry::from_operation(&op1, "success", None)).expect("TODO: handle error");
327+
log.append(&AuditEntry::from_operation(&op1, "success", None)).unwrap();
328328

329329
let op2 = Operation::new(OperationType::CreateFile, "file1".to_string(), None);
330-
log.append(&AuditEntry::from_operation(&op2, "success", None)).expect("TODO: handle error");
330+
log.append(&AuditEntry::from_operation(&op2, "success", None)).unwrap();
331331

332332
let op3 = Operation::new(OperationType::Mkdir, "dir2".to_string(), None);
333-
log.append(&AuditEntry::from_operation(&op3, "success", None)).expect("TODO: handle error");
333+
log.append(&AuditEntry::from_operation(&op3, "success", None)).unwrap();
334334

335-
let mkdirs = log.read_by_type("Mkdir").expect("TODO: handle error");
335+
let mkdirs = log.read_by_type("Mkdir").unwrap();
336336
assert_eq!(mkdirs.len(), 2);
337337
assert_eq!(mkdirs[0].path, "dir1");
338338
assert_eq!(mkdirs[1].path, "dir2");

impl/rust-cli/src/functions.rs

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -313,11 +313,13 @@ fn parse_function_body(body_str: &str) -> Vec<String> {
313313
/// Same rules as variable names: starts with letter or underscore,
314314
/// then alphanumeric or underscore.
315315
pub fn is_valid_function_name(name: &str) -> bool {
316-
if name.is_empty() {
317-
return false;
318-
}
316+
// `let-else` covers the empty-name case directly: chars.next() returns
317+
// None on an empty &str, which is the same outcome as the previous
318+
// explicit `if name.is_empty()` guard. One construct, no panic site.
319319
let mut chars = name.chars();
320-
let first = chars.next().expect("TODO: handle error");
320+
let Some(first) = chars.next() else {
321+
return false;
322+
};
321323
if !first.is_alphabetic() && first != '_' {
322324
return false;
323325
}
@@ -336,7 +338,7 @@ mod tests {
336338
fn test_parse_posix_function_def() {
337339
let result = parse_function_def("greet() { echo hello; }");
338340
assert!(result.is_some());
339-
let (name, body, raw_body) = result.expect("TODO: handle error");
341+
let (name, body, raw_body) = result.unwrap();
340342
assert_eq!(name, "greet");
341343
assert_eq!(body, vec!["echo hello"]);
342344
// raw_body preserves the trailing `;` — that's harmless.
@@ -347,7 +349,7 @@ mod tests {
347349
fn test_parse_posix_function_multi_commands() {
348350
let result = parse_function_def("setup() { mkdir src; touch src/main.rs; echo done; }");
349351
assert!(result.is_some());
350-
let (name, body, raw_body) = result.expect("TODO: handle error");
352+
let (name, body, raw_body) = result.unwrap();
351353
assert_eq!(name, "setup");
352354
assert_eq!(body, vec!["mkdir src", "touch src/main.rs", "echo done"]);
353355
assert_eq!(raw_body, "mkdir src; touch src/main.rs; echo done;");
@@ -357,7 +359,7 @@ mod tests {
357359
fn test_parse_bash_function_def() {
358360
let result = parse_function_def("function greet { echo hello; }");
359361
assert!(result.is_some());
360-
let (name, body, raw_body) = result.expect("TODO: handle error");
362+
let (name, body, raw_body) = result.unwrap();
361363
assert_eq!(name, "greet");
362364
assert_eq!(body, vec!["echo hello"]);
363365
assert_eq!(raw_body, "echo hello;");
@@ -367,7 +369,7 @@ mod tests {
367369
fn test_parse_bash_function_with_parens() {
368370
let result = parse_function_def("function greet() { echo hello; }");
369371
assert!(result.is_some());
370-
let (name, body, raw_body) = result.expect("TODO: handle error");
372+
let (name, body, raw_body) = result.unwrap();
371373
assert_eq!(name, "greet");
372374
assert_eq!(body, vec!["echo hello"]);
373375
assert_eq!(raw_body, "echo hello;");
@@ -379,7 +381,7 @@ mod tests {
379381
// execution can parse `if/fi`, `for/done`, etc. as single commands.
380382
let result = parse_function_def("ifunc() { if true; then mkdir d; fi; }");
381383
assert!(result.is_some());
382-
let (name, _body, raw_body) = result.expect("TODO: handle error");
384+
let (name, _body, raw_body) = result.unwrap();
383385
assert_eq!(name, "ifunc");
384386
assert_eq!(raw_body, "if true; then mkdir d; fi;");
385387
}
@@ -389,7 +391,7 @@ mod tests {
389391
// A `}` inside a quoted string must NOT be treated as the closing brace.
390392
let result = parse_function_def("lit() { echo '}'; }");
391393
assert!(result.is_some());
392-
let (_name, _body, raw_body) = result.expect("TODO: handle error");
394+
let (_name, _body, raw_body) = result.unwrap();
393395
assert_eq!(raw_body, "echo '}';");
394396
}
395397

@@ -476,7 +478,7 @@ mod tests {
476478
line: 5,
477479
},
478480
});
479-
let def = table.get("greet").expect("TODO: handle error");
481+
let def = table.get("greet").unwrap();
480482
assert_eq!(def.body, vec!["echo goodbye"]);
481483
}
482484

@@ -495,11 +497,11 @@ mod tests {
495497
table.push_frame(vec!["nested_arg".to_string()]);
496498
assert_eq!(table.call_depth(), 2);
497499

498-
let frame = table.pop_frame().expect("TODO: handle error");
500+
let frame = table.pop_frame().unwrap();
499501
assert_eq!(frame.saved_params, vec!["nested_arg"]);
500502
assert_eq!(table.call_depth(), 1);
501503

502-
let frame = table.pop_frame().expect("TODO: handle error");
504+
let frame = table.pop_frame().unwrap();
503505
assert_eq!(frame.saved_params, vec!["arg1", "arg2"]);
504506
assert_eq!(table.call_depth(), 0);
505507

@@ -514,7 +516,7 @@ mod tests {
514516
table.declare_local("x", Some("old_value".to_string()));
515517
table.declare_local("y", None);
516518

517-
let frame = table.pop_frame().expect("TODO: handle error");
519+
let frame = table.pop_frame().unwrap();
518520
assert_eq!(frame.local_vars, vec!["x", "y"]);
519521
assert_eq!(
520522
frame.saved_vars.get("x"),
@@ -533,7 +535,7 @@ mod tests {
533535
// Second declaration in same frame should NOT overwrite the saved value
534536
table.declare_local("x", Some("modified".to_string()));
535537

536-
let frame = table.pop_frame().expect("TODO: handle error");
538+
let frame = table.pop_frame().unwrap();
537539
// The saved value should be "original", not "modified"
538540
assert_eq!(
539541
frame.saved_vars.get("x"),

impl/rust-cli/src/job.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ mod tests {
214214

215215
let job = table.get_job("%1");
216216
assert!(job.is_some());
217-
assert_eq!(job.expect("TODO: handle error").pgid, 1234);
217+
assert_eq!(job.unwrap().pgid, 1234);
218218
}
219219

220220
#[test]
@@ -226,12 +226,12 @@ mod tests {
226226
// %+ should be most recent (id2)
227227
let job = table.get_job("%+");
228228
assert!(job.is_some());
229-
assert_eq!(job.expect("TODO: handle error").id, id2);
229+
assert_eq!(job.unwrap().id, id2);
230230

231231
// %- should be previous (id1)
232232
let job = table.get_job("%-");
233233
assert!(job.is_some());
234-
assert_eq!(job.expect("TODO: handle error").id, id1);
234+
assert_eq!(job.unwrap().id, id1);
235235
}
236236

237237
#[test]
@@ -242,11 +242,11 @@ mod tests {
242242

243243
let job = table.get_job("%sleep");
244244
assert!(job.is_some());
245-
assert_eq!(job.expect("TODO: handle error").command, "sleep 10");
245+
assert_eq!(job.unwrap().command, "sleep 10");
246246

247247
let job = table.get_job("%find");
248248
assert!(job.is_some());
249-
assert_eq!(job.expect("TODO: handle error").command, "find / -name test");
249+
assert_eq!(job.unwrap().command, "find / -name test");
250250
}
251251

252252
#[test]
@@ -256,7 +256,7 @@ mod tests {
256256

257257
let job = table.get_job("%?name");
258258
assert!(job.is_some());
259-
assert_eq!(job.expect("TODO: handle error").command, "find / -name test");
259+
assert_eq!(job.unwrap().command, "find / -name test");
260260
}
261261

262262
#[test]
@@ -275,7 +275,7 @@ mod tests {
275275
table.add_job(1234, "sleep 10".to_string(), vec![1234]);
276276

277277
table.update_job_state(1234, JobState::Stopped);
278-
let job = table.get_job("%1").expect("TODO: handle error");
278+
let job = table.get_job("%1").unwrap();
279279
assert_eq!(job.state, JobState::Stopped);
280280
}
281281

impl/rust-cli/src/process_sub.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -241,54 +241,54 @@ mod tests {
241241

242242
#[test]
243243
fn test_fifo_creation() {
244-
let temp_dir = TempDir::new().expect("TODO: handle error");
245-
let mut state = ShellState::new(temp_dir.path().to_str().expect("TODO: handle error")).expect("TODO: handle error");
244+
let temp_dir = TempDir::new().unwrap();
245+
let mut state = ShellState::new(temp_dir.path().to_str().unwrap()).unwrap();
246246

247247
let proc_sub = ProcessSubstitution::create(
248248
ProcessSubType::Input,
249249
"echo test".to_string(),
250250
&mut state,
251-
).expect("TODO: handle error");
251+
).unwrap();
252252

253253
// FIFO should exist
254254
assert!(proc_sub.fifo_path.exists());
255255

256256
// Should be a FIFO
257257
#[cfg(unix)]
258258
{
259-
let metadata = std::fs::metadata(&proc_sub.fifo_path).expect("TODO: handle error");
259+
let metadata = std::fs::metadata(&proc_sub.fifo_path).unwrap();
260260
use std::os::unix::fs::FileTypeExt;
261261
assert!(metadata.file_type().is_fifo());
262262
}
263263

264264
// Cleanup should remove FIFO
265265
let fifo_path = proc_sub.fifo_path.clone();
266-
proc_sub.cleanup().expect("TODO: handle error");
266+
proc_sub.cleanup().unwrap();
267267
assert!(!fifo_path.exists());
268268
}
269269

270270
#[test]
271271
fn test_fifo_path_unique() {
272-
let temp_dir = TempDir::new().expect("TODO: handle error");
273-
let mut state = ShellState::new(temp_dir.path().to_str().expect("TODO: handle error")).expect("TODO: handle error");
272+
let temp_dir = TempDir::new().unwrap();
273+
let mut state = ShellState::new(temp_dir.path().to_str().unwrap()).unwrap();
274274

275275
let proc_sub1 = ProcessSubstitution::create(
276276
ProcessSubType::Input,
277277
"echo a".to_string(),
278278
&mut state,
279-
).expect("TODO: handle error");
279+
).unwrap();
280280

281281
let proc_sub2 = ProcessSubstitution::create(
282282
ProcessSubType::Input,
283283
"echo b".to_string(),
284284
&mut state,
285-
).expect("TODO: handle error");
285+
).unwrap();
286286

287287
// FIFOs should have different paths
288288
assert_ne!(proc_sub1.fifo_path, proc_sub2.fifo_path);
289289

290290
// Cleanup
291-
proc_sub1.cleanup().expect("TODO: handle error");
292-
proc_sub2.cleanup().expect("TODO: handle error");
291+
proc_sub1.cleanup().unwrap();
292+
proc_sub2.cleanup().unwrap();
293293
}
294294
}

0 commit comments

Comments
 (0)