Skip to main content

agent_sessions/
error.rs

1use serde::Serialize;
2use std::{fmt, io, path::PathBuf};
3
4/// The failed discovery operation. `InspectFile` identifies a candidate already
5/// observed as a regular JSONL file, so consumers can apply their metadata policy.
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7#[non_exhaustive]
8pub enum DiscoverOperation {
9    DirectoryMetadata,
10    ReadDirectory,
11    ReadEntry,
12    FileType,
13    InspectFile,
14}
15
16#[derive(Debug)]
17pub struct DiscoverError {
18    pub agent: crate::Agent,
19    pub operation: DiscoverOperation,
20    pub path: PathBuf,
21    pub source: io::Error,
22}
23
24#[derive(Debug)]
25#[non_exhaustive]
26pub enum ReadError {
27    Io(io::Error),
28    TooLarge { limit: u64 },
29    InvalidOptions(&'static str),
30    Format(LineErrorKind),
31    Database(rusqlite::Error),
32}
33
34#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
35#[non_exhaustive]
36pub enum LineErrorKind {
37    InvalidJson,
38    InvalidUtf8,
39    TooLong,
40    MissingField(&'static str),
41    InvalidField(String),
42    CounterRegression,
43    LostUsageBaseline,
44}
45
46#[derive(Debug)]
47#[non_exhaustive]
48pub enum StreamError {
49    Line {
50        line_no: u64,
51        byte_start: u64,
52        kind: LineErrorKind,
53    },
54    Io(io::Error),
55    TooLarge {
56        limit: u64,
57    },
58    SnapshotTruncated {
59        expected: u64,
60        actual: u64,
61    },
62}
63
64impl fmt::Display for ReadError {
65    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66        match self {
67            Self::Io(_) => write!(f, "cannot open session file"),
68            Self::TooLarge { limit } => write!(f, "session exceeds {limit} byte limit"),
69            Self::InvalidOptions(msg) => write!(f, "invalid read options: {msg}"),
70            Self::Format(kind) => write!(f, "invalid session format: {kind:?}"),
71            Self::Database(_) => write!(f, "cannot read session database"),
72        }
73    }
74}
75impl std::error::Error for ReadError {
76    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
77        match self {
78            Self::Io(e) => Some(e),
79            Self::Database(e) => Some(e),
80            _ => None,
81        }
82    }
83}
84impl fmt::Display for StreamError {
85    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86        match self {
87            Self::Line { line_no, kind, .. } => write!(f, "session line {line_no}: {kind:?}"),
88            Self::Io(_) => write!(f, "session read failed"),
89            Self::TooLarge { limit } => write!(f, "session exceeds {limit} byte limit"),
90            Self::SnapshotTruncated { expected, actual } => {
91                write!(f, "snapshot requires {expected} bytes; read {actual}")
92            }
93        }
94    }
95}
96impl std::error::Error for StreamError {
97    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
98        match self {
99            Self::Io(e) => Some(e),
100            _ => None,
101        }
102    }
103}