1use std::borrow::Cow;
2
3use anyhow::{Error, Result};
4
5pub const ERR_READ_FILE: &str = "failed to read file";
7pub const ERR_WRITE_FILE: &str = "failed to write file";
8pub const ERR_READ_DIR: &str = "failed to read directory";
9pub const ERR_CREATE_DIR: &str = "failed to create directory";
10pub const ERR_REMOVE_FILE: &str = "failed to remove file";
11pub const ERR_REMOVE_DIR: &str = "failed to remove directory";
12pub const ERR_READ_DIR_ENTRY: &str = "failed to read directory entry";
13pub const ERR_GET_FILE_TYPE: &str = "failed to read file type";
14pub const ERR_GET_METADATA: &str = "failed to read file metadata";
15pub const ERR_CANONICALIZE_PATH: &str = "failed to canonicalize path";
16pub const ERR_READ_SYMLINK: &str = "failed to read symlink";
17
18pub const ERR_CREATE_SKILLS_DIR: &str = "failed to create skills directory";
20pub const ERR_CREATE_SKILL_DIR: &str = "failed to create skill directory";
21pub const ERR_READ_SKILL_CODE: &str = "failed to read skill code";
22pub const ERR_WRITE_SKILL_CODE: &str = "failed to write skill code";
23pub const ERR_READ_SKILL_METADATA: &str = "failed to read skill metadata";
24pub const ERR_WRITE_SKILL_METADATA: &str = "failed to write skill metadata";
25pub const ERR_PARSE_SKILL_METADATA: &str = "failed to parse skill metadata";
26pub const ERR_WRITE_SKILL_DOCS: &str = "failed to write skill documentation";
27pub const ERR_DELETE_SKILL: &str = "failed to delete skill";
28pub const ERR_READ_SKILLS_DIR: &str = "failed to read skills directory";
29pub const ERR_TOOL_DENIED: &str = "tool denied or unavailable by policy";
30
31pub const ERR_CREATE_AUDIT_DIR: &str = "Failed to create audit directory";
33pub const ERR_WRITE_AUDIT_LOG: &str = "failed to write audit log";
34
35pub const ERR_CREATE_CHECKPOINT_DIR: &str = "failed to create checkpoint directory";
37pub const ERR_WRITE_CHECKPOINT: &str = "failed to write checkpoint";
38pub const ERR_READ_CHECKPOINT: &str = "failed to read checkpoint";
39
40pub const ERR_CREATE_POLICY_DIR: &str = "Failed to create directory for tool policy config";
42pub const ERR_CREATE_WORKSPACE_POLICY_DIR: &str = "Failed to create workspace policy directory";
43
44pub const ERR_SERIALIZE_METADATA: &str = "failed to serialize skill metadata";
46pub const ERR_SERIALIZE_STATE: &str = "failed to serialize state";
47pub const ERR_DESERIALIZE: &str = "failed to deserialize data";
48
49pub const ERR_CREATE_IPC_DIR: &str = "failed to create IPC directory";
51pub const ERR_READ_REQUEST_FILE: &str = "failed to read request file";
52pub const ERR_READ_REQUEST_JSON: &str = "failed to read request JSON";
53pub const ERR_PARSE_REQUEST_JSON: &str = "failed to parse request JSON";
54pub const ERR_PARSE_ARGS: &str = "failed to parse tokenized args";
55pub const ERR_PARSE_RESULT: &str = "failed to parse de-tokenized result";
56
57#[macro_export]
60macro_rules! file_err {
61 ($path:expr, read) => {
62 format!("failed to read {}", $path)
63 };
64 ($path:expr, write) => {
65 format!("failed to write {}", $path)
66 };
67 ($path:expr, delete) => {
68 format!("failed to delete {}", $path)
69 };
70 ($path:expr, create) => {
71 format!("failed to create {}", $path)
72 };
73}
74
75#[macro_export]
78macro_rules! ctx_err {
79 ($op:expr, $ctx:expr) => {
80 format!("{}: {}", $op, $ctx)
81 };
82}
83
84pub trait ErrorFormatter: Send + Sync {
88 fn format_error(&self, error: &Error) -> Cow<'_, str>;
90}
91
92pub trait ErrorReporter: Send + Sync {
94 fn capture(&self, error: &Error) -> Result<()>;
96
97 fn capture_message(&self, message: impl Into<Cow<'static, str>>) -> Result<()> {
99 let message: Cow<'static, str> = message.into();
100 self.capture(&Error::msg(message))
101 }
102}
103
104#[derive(Debug, Default, Clone, Copy)]
107pub struct NoopErrorReporter;
108
109impl ErrorReporter for NoopErrorReporter {
110 fn capture(&self, _error: &Error) -> Result<()> {
111 Ok(())
112 }
113}
114
115#[derive(Debug, Default, Clone, Copy)]
117pub struct DisplayErrorFormatter;
118
119impl ErrorFormatter for DisplayErrorFormatter {
120 fn format_error(&self, error: &Error) -> Cow<'_, str> {
121 Cow::Owned(format!("{error}"))
122 }
123}
124
125#[cfg(test)]
126mod tests {
127 use super::*;
128
129 #[test]
130 fn formatter_uses_display() {
131 let formatter = DisplayErrorFormatter;
132 let error = Error::msg("test error");
133 assert_eq!(formatter.format_error(&error), "test error");
134 }
135
136 #[test]
137 fn noop_reporter_drops_errors() {
138 let reporter = NoopErrorReporter;
139 let error = Error::msg("test");
140 assert!(reporter.capture(&error).is_ok());
141 assert!(reporter.capture_message("message").is_ok());
142 }
143}