Skip to main content

kcode_k1_chat_thread_web_code_errors/
lib.rs

1#![forbid(unsafe_code)]
2
3use kcode_k1_chat_boxes::ToolCallId;
4use kcode_k1_chat_web_code_output::{self as output, Operation, WebCodeOutput};
5use kcode_k1_web_code_ktool_service::{ServiceError, ServiceFailure};
6
7pub fn service_error(
8    tool_call_id: ToolCallId,
9    operation: Operation,
10    service_error: ServiceError,
11) -> WebCodeOutput {
12    let code = match service_error.failure() {
13        ServiceFailure::State => "state",
14        ServiceFailure::Authorization => "authorization",
15        ServiceFailure::WorkspaceDenied => "workspace_denied",
16        ServiceFailure::SourceUnavailable => "source_unavailable",
17        ServiceFailure::LanguageRequired => "language_required",
18        ServiceFailure::LanguageMismatch => "language_mismatch",
19        ServiceFailure::ForeignHandle => "foreign_handle",
20        ServiceFailure::StaleSource => "stale_source",
21        ServiceFailure::InvalidDocument => "invalid_document",
22        ServiceFailure::CheckFailed => "check_failed",
23        ServiceFailure::SourcePreservation => "source_preservation",
24        ServiceFailure::PublicReleaseDenied => "public_release_denied",
25        ServiceFailure::Publication => "publication",
26        ServiceFailure::Dependency => "dependency",
27    };
28    let source_object = service_error
29        .source_object()
30        .map(|source_object| source_object.to_string());
31    error(
32        tool_call_id,
33        operation,
34        code,
35        service_error.to_string(),
36        source_object.as_deref(),
37    )
38}
39
40pub fn error(
41    tool_call_id: ToolCallId,
42    operation: Operation,
43    code: &str,
44    message: String,
45    source_object: Option<&str>,
46) -> WebCodeOutput {
47    output::error(
48        tool_call_id,
49        Vec::new(),
50        Err(message),
51        operation,
52        code,
53        source_object,
54    )
55}
56
57pub fn simple_error(
58    tool_call_id: ToolCallId,
59    operation: Operation,
60    code: &'static str,
61) -> WebCodeOutput {
62    error(tool_call_id, operation, code, code.replace('_', " "), None)
63}
64
65#[cfg(test)]
66mod tests {
67    use super::*;
68    use kcode_k1_chat_web_code_output::WEB_CODE_PUBLISH_METADATA_TYPE;
69
70    fn tool_call_id() -> ToolCallId {
71        ToolCallId::new([0x3c; 12], 17)
72    }
73
74    #[test]
75    fn generic_error_preserves_safe_text_source_object_and_metadata() {
76        let output = error(
77            tool_call_id(),
78            Operation::Publish,
79            "publication",
80            "complete safe text\nwith details".to_owned(),
81            Some("abcdef0123456789abcdef01"),
82        );
83
84        assert_eq!(output.tool_call_id, tool_call_id());
85        assert!(output.messages.is_empty());
86        assert_eq!(
87            output.result,
88            Err("complete safe text\nwith details".to_owned())
89        );
90        assert_eq!(output.metadata_type, WEB_CODE_PUBLISH_METADATA_TYPE);
91        assert_eq!(
92            output.metadata_contents,
93            r#"{"status":"error","code":"publication","source_object":"abcdef0123456789abcdef01"}"#
94        );
95    }
96
97    #[test]
98    fn simple_error_derives_safe_text_and_has_no_source_object() {
99        let output = simple_error(tool_call_id(), Operation::Publish, "public_release_denied");
100
101        assert!(output.messages.is_empty());
102        assert_eq!(output.result, Err("public release denied".to_owned()));
103        assert_eq!(
104            output.metadata_contents,
105            r#"{"status":"error","code":"public_release_denied","source_object":null}"#
106        );
107    }
108}