Major documentation restructure to improve discoverability and reduce duplication. ## Changes **Deleted (Archived/Consolidated)**: - Removed duplicate getting started guides - Archived outdated planning documents - Consolidated corpus and configuration docs - Removed obsolete vision/spec files (superseded by vision.md) - Cleaned up scrapyard and old PDFs **New Structure**: - docs/about/ - Project overview and introduction - docs/guides/ - User guides (moved from root) - docs/specs/ - Technical specifications - docs/sdk/ - SDK documentation (Go) - docs/references/ - API references - docs/archive/ - Archived historical docs - applications/aphoria/docs/advanced/ - Advanced topics - applications/aphoria/docs/reference/ - CLI reference - applications/aphoria/docs/archive/ - Archived aphoria docs **Updated**: - README.md - New root README with clear navigation - CONTRIBUTING.md - Contribution guidelines - CLAUDE.md - Updated paths to new structure - roadmap.md - Added recent completions ## Files Changed - 57 files changed - 1,977 insertions(+) - 961 deletions(-) **Net change**: +1,016 lines (added CONTRIBUTING.md, README.md, reorganized content) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
70 lines
2.1 KiB
Markdown
70 lines
2.1 KiB
Markdown
# Error Handling Pattern
|
|
|
|
**Last Updated:** 2026-01-31
|
|
**Confidence:** High
|
|
|
|
## Summary
|
|
|
|
StemeDB uses `thiserror` for library errors with context chains. No panics in production code. All fallible operations return `Result<T, E>`.
|
|
|
|
**Key Facts:**
|
|
- Library code: `thiserror` for custom error types — ALL error enums MUST use `#[derive(thiserror::Error)]`
|
|
- Binary code: `anyhow` for error chaining
|
|
- Never use `unwrap()`, `expect()`, `panic!()` in production
|
|
- Add context with `.context("what we were doing")?`
|
|
- NEVER use manual `impl Display` + `impl Error` for error types — use thiserror derives instead
|
|
|
|
**Error types in workspace (all use thiserror):**
|
|
- `stemedb-core/src/serde.rs` — `SerdeError`
|
|
- `stemedb-wal/src/error.rs` — `QuarantineError`
|
|
- `stemedb-storage/src/error.rs` — `StorageError`
|
|
- `stemedb-ingest/src/error.rs` — `IngestError`
|
|
- `stemedb-query/src/error.rs` — `QueryError`
|
|
- `stemedb-api/src/error.rs` — `ApiError`
|
|
|
|
## The Pattern
|
|
|
|
```rust
|
|
use thiserror::Error;
|
|
|
|
#[derive(Debug, Error)]
|
|
pub enum StemeError {
|
|
#[error("assertion not found: {0:?}")]
|
|
NotFound(Hash),
|
|
|
|
#[error("invalid signature for agent {agent:?}")]
|
|
InvalidSignature { agent: AgentId },
|
|
|
|
#[error("storage error: {0}")]
|
|
Storage(String),
|
|
|
|
#[error("serialization error: {0}")]
|
|
Serialization(String),
|
|
}
|
|
|
|
// Usage with context
|
|
fn load_assertion(&self, hash: &Hash) -> Result<Assertion, StemeError> {
|
|
let bytes = self.store
|
|
.get(hash.as_bytes())
|
|
.context("failed to read assertion from store")?
|
|
.ok_or(StemeError::NotFound(*hash))?;
|
|
|
|
rkyv::from_bytes(&bytes)
|
|
.map_err(|e| StemeError::Serialization(e.to_string()))
|
|
}
|
|
```
|
|
|
|
## Error Categories
|
|
|
|
| Type | Description | Example |
|
|
|------|-------------|---------|
|
|
| `NotFound` | Data doesn't exist | Missing assertion |
|
|
| `InvalidSignature` | Crypto verification failed | Tampered assertion |
|
|
| `Storage` | Underlying KV error | Disk full |
|
|
| `Serialization` | Encode/decode failed | Corrupt data |
|
|
|
|
## Related Topics
|
|
|
|
- [Rust Guidelines](../../.claude/guides/backend/rust-guidelines.md)
|
|
- [Coding Guidelines](../../../.claude/guides/coding-guidelines.md)
|