Skip to main content

roomrs_core/
error.rs

1//! roomrs 단일 에러 타입 (명세 §12, 결정 로그 16)
2
3/// roomrs 공용 Result 별칭
4pub type Result<T, E = Error> = std::result::Result<T, E>;
5
6/// roomrs 단일 에러 타입 — 공개 API는 전부 이 타입으로 반환한다
7#[derive(Debug, thiserror::Error)]
8#[non_exhaustive]
9pub enum Error {
10    /// SQLite 하부 에러 (rusqlite 위임 — readonly 계열은 `ReadOnly`로 매핑, L-2)
11    #[error("SQLite 에러: {0}")]
12    Sqlite(rusqlite::Error),
13
14    /// 정확히 1건을 기대했으나 0건 (명세 §5.2 반환 타입 규칙)
15    #[error("행을 찾을 수 없습니다 (정확히 1건 기대, 0건 반환)")]
16    NotFound,
17
18    /// SQLite가 읽기 전용 상태 또는 파일로 판단한 write.
19    #[error("읽기 전용 커넥션에 쓰기를 시도했습니다: {0}")]
20    ReadOnly(String),
21
22    /// 통합 풀 checkout 대기 타임아웃 (명세 §10 큐 정책)
23    #[error("커넥션 풀 대기가 타임아웃되었습니다 ({0:?})")]
24    QueueTimeout(std::time::Duration),
25
26    /// 마이그레이션 실패/불가
27    #[error("마이그레이션 에러: {0}")]
28    Migration(String),
29
30    /// 스키마 스냅샷 스테일 (명세 §7.4 — M1c에서 사용)
31    #[error("스키마 스냅샷이 오래되었습니다: {0}")]
32    SnapshotStale(String),
33
34    /// 라이브 쿼리 의존 테이블 추출 실패 (명세 §5.7 — M4에서 사용)
35    #[error("쿼리의 의존 테이블을 알 수 없습니다: {0}")]
36    UnknownDependencies(String),
37
38    /// 빌더/설정 오류
39    #[error("설정 에러: {0}")]
40    Config(String),
41
42    /// 내부 불변식 위반 — 워커 응답 유실 등 (버그 신고 대상)
43    #[error("내부 에러: {0}")]
44    Internal(String),
45
46    /// 데이터베이스 종료 — 라이브 쿼리 채널 닫힘 (M-7)
47    #[error("데이터베이스가 종료되어 라이브 쿼리 채널이 닫혔습니다")]
48    Closed,
49
50    /// JSON 직렬화/역직렬화 실패 (`#[json]` 필드)
51    #[cfg(feature = "json")]
52    #[error("JSON 변환 에러: {0}")]
53    Json(#[from] serde_json::Error),
54}
55
56/// rusqlite 에러 변환 — SQLITE_READONLY는 공개 호환용 `ReadOnly`로 승격한다.
57impl From<rusqlite::Error> for Error {
58    fn from(e: rusqlite::Error) -> Self {
59        match &e {
60            rusqlite::Error::SqliteFailure(fe, _) if fe.code == rusqlite::ErrorCode::ReadOnly => {
61                Error::ReadOnly(e.to_string())
62            }
63            _ => Error::Sqlite(e),
64        }
65    }
66}