# Error Handling Audit Report

**Audit Date:** 2026-01-22  
**Auditor:** Code Quality Agent  
**Scope:** Production code in do-memory-core, do-memory-mcp, do-memory-cli, do-memory-storage-turso, do-memory-storage-redb  
**Exclusions:** tests/*, benches/*, examples/*, do-memory-test-utils/*, *_test.rs, *test*.rs

---

## Executive Summary

| Metric | Count |
|--------|-------|
| `.unwrap()` calls | 96 |
| `.expect()` calls | 47 |
| **Grand Total** | **143** |

### Comparison to Plan Claims

| Source | Count | Notes |
|--------|-------|-------|
| Plan claimed (production only) | 598 | Disputed |
| Plan counted (including tests) | 3,225 | Disputed |
| **Actual audit (production only)** | **143** | Verified |

> **Finding:** The actual count of `.unwrap()` and `.expect()` calls in production code is significantly lower than the plan's claim of 598. The plan's numbers appear to include test code or were overestimated.

---

## Category Breakdown

### 1. Hot Path Operations (38.5%)

**Total:** 55 calls (46 `.unwrap()`, 9 `.expect()`)

These are performance-critical operations in the retrieval and embedding pipelines. Some use of unwrap in hot paths can be justified for performance, but should be well-documented.

| File | Count | Type |
|------|-------|------|
| `do-memory-core/src/embeddings/local.rs` | 14 | unwrap |
| `do-memory-core/src/retrieval/cache/lru.rs` | 8 | expect |
| `do-memory-core/src/patterns/extractors/hybrid.rs` | 6 | unwrap |
| `do-memory-core/src/patterns/extractors/context_pattern.rs` | 3 | unwrap |
| `do-memory-core/src/patterns/extractors/decision_point.rs` | 3 | unwrap |
| `do-memory-core/src/patterns/extractors/error_recovery.rs` | 3 | unwrap |
| `do-memory-core/src/patterns/extractors/tool_sequence.rs` | 3 | unwrap |

**Risk Assessment:** Medium - These are in performance-sensitive code paths where panics could affect throughput.

---

### 2. Configuration (8.4%)

**Total:** 12 calls (3 `.unwrap()`, 9 `.expect()`)

Configuration parsing and validation. These should use proper error handling.

| File | Count | Type |
|------|-------|------|
| `do-memory-cli/src/config/types.rs` | 4 | expect |
| `do-memory-cli/src/config/loader/cache.rs` | 5 | expect |
| `do-memory-cli/src/config/progressive/simple_setup.rs` | 2 | unwrap |
| `do-memory-cli/src/config/progressive/quick_setup.rs` | 1 | unwrap |

**Risk Assessment:** Low-Medium - Configuration errors should fail gracefully with meaningful error messages.

---

### 3. Database Operations (5.6%)

**Total:** 8 calls (4 `.unwrap()`, 4 `.expect()`)

Database and storage layer operations.

| File | Count | Type |
|------|-------|------|
| `do-memory-storage-turso/src/resilient.rs` | 4 | unwrap |
| `do-memory-core/src/retrieval/cache/lru.rs` | 4 | expect |

**Risk Assessment:** High - Database operations can fail for many reasons (network, disk, schema). Proper error handling is critical.

---

### 4. Other / Infrastructure (47.6%)

**Total:** 68 calls (43 `.unwrap()`, 25 `.expect()`)

Infrastructure code including:

- Lock poisoning checks (RwLock/Mutex)
- Circuit breaker state
- Sandboxing
- Monitoring

| File | Count | Type |
|------|-------|------|
| `do-memory-core/src/monitoring/core.rs` | 13 | unwrap |
| `do-memory-core/src/retrieval/cache/lru.rs` | 10 | expect |
| `do-memory-core/src/embeddings/local.rs` | 8 | unwrap |
| `do-memory-mcp/src/batch/executor.rs` | 8 | unwrap |
| `do-memory-core/src/embeddings/circuit_breaker.rs` | 6 | expect |

**Risk Assessment:** Low-Medium - Lock poisoning checks are defensive; panics here indicate serious concurrency bugs.

---

## Crate Breakdown

| Crate | Total | `.unwrap()` | `.expect()` |
|-------|-------|-------------|-------------|
| do-memory-core | 98 | 68 | 30 |
| do-memory-mcp | 21 | 20 | 1 |
| do-memory-cli | 19 | 3 | 16 |
| do-memory-storage-turso | 5 | 5 | 0 |
| do-memory-storage-redb | 0 | 0 | 0 |
| **Total** | **143** | **96** | **47** |

---

## Files with Highest Counts

| File | Total | Risk Level |
|------|-------|------------|
| `do-memory-core/src/embeddings/local.rs` | 25 | High |
| `do-memory-core/src/retrieval/cache/lru.rs` | 22 | Medium |
| `do-memory-core/src/monitoring/core.rs` | 13 | Low |
| `do-memory-mcp/src/batch/executor.rs` | 8 | Medium |
| `do-memory-core/src/patterns/extractors/hybrid.rs` | 6 | Medium |
| `do-memory-storage-turso/src/resilient.rs` | 5 | High |
| `do-memory-core/src/embeddings/circuit_breaker.rs` | 6 | Low |
| `do-memory-cli/src/config/loader/cache.rs` | 8 | Medium |

---

## Recommendations

### Priority 1: Database Operations (High Risk)

**Files:** `do-memory-storage-turso/src/resilient.rs` (4 unwraps)

Replace with proper error handling:

```rust
// BEFORE
self.connection.execute(query).unwrap();

// AFTER
self.connection.execute(query)
    .context("Failed to execute query")?;
```

### Priority 2: Hot Path Operations (Medium Risk)

**Files:** `do-memory-core/src/embeddings/local.rs`, pattern extractors

For truly hot paths where performance is critical, document why unwrap is acceptable:

```rust
// Use expect with clear error message for debugging
self.cache.get(&key).expect("Cache lookup should always succeed for valid keys")
```

Consider adding runtime checks to convert panics into errors:

```rust
// Option 1: Convert to Result
fn get_or_insert(&self, key: K) -> Result<V, CacheError> {
    self.cache.get(&key).ok_or(CacheError::KeyNotFound)
}

// Option 2: Use parking_lot::RwLock (doesn't poison)
use parking_lot::RwLock;
```

### Priority 3: Configuration (Low-Medium Risk)

**Files:** `do-memory-cli/src/config/*`

These should use `?` operator with proper error types:

```rust
// BEFORE
let value = config.get("key").expect("Config key must exist");

// AFTER
let value = config.get("key")
    .ok_or(ConfigError::MissingKey("key".to_string()))?;
```

### Priority 4: Lock Poisoning (Low Risk)

**Files:** `do-memory-core/src/retrieval/cache/lru.rs` (21 expects)

Lock poisoning checks are defensive. Options:

1. **Keep as-is** - Panics indicate serious bugs that should be caught
2. **Use `parking_lot`** - Doesn't poison on panic
3. **Ignore poison** - Use `lock().ignore_poisoned()` for resilience

---

## Summary of Recommended Actions

| Priority | Category | Count | Action |
|----------|----------|-------|--------|
| 1 | Database | 8 | Replace with proper error handling |
| 2 | Hot Path | 55 | Document rationale or use fallible operations |
| 3 | Configuration | 12 | Replace with `?` operator and proper errors |
| 4 | Other | 68 | Evaluate case-by-case |

**Estimated Effort:**
- Quick fixes (configuration): ~1 hour
- Medium refactoring (database): ~2-4 hours
- Hot path evaluation: ~4-8 hours (requires performance analysis)

---

## Conclusion

The actual count of `.unwrap()` and `.expect()` in production code (**143**) is significantly lower than the plan's claim (**598**). Most calls fall into acceptable categories:

1. **Lock poisoning checks** (defensive, low risk)
2. **Configuration parsing** (should be fixed)
3. **Hot path operations** (may be justified for performance)

The primary concern is the **8 database operations** that should use proper error handling. The remaining calls are mostly acceptable or can be addressed incrementally.
