languagetool_rust/
error.rs1use std::process::ExitStatus;
4
5#[derive(Debug, thiserror::Error)]
7pub enum Error {
8 #[cfg(feature = "cli")]
10 #[error(transparent)]
11 Cli(#[from] clap::Error),
12
13 #[error("command not found: {0}")]
15 CommandNotFound(String),
16
17 #[error("command failed: {0:?}")]
19 ExitStatus(String),
20
21 #[error("invalid request: {0}")]
24 InvalidDataAnnotation(String),
25
26 #[error("invalid filename (got '{0}', does not exist or is not a file)")]
28 InvalidFilename(String),
29
30 #[error("invalid request: {0}")]
32 InvalidRequest(String),
33
34 #[error("invalid value: {0:?}")]
36 InvalidValue(String),
37
38 #[error(transparent)]
40 IO(#[from] std::io::Error),
41
42 #[cfg(feature = "multithreaded")]
44 #[error(transparent)]
45 JoinError(#[from] tokio::task::JoinError),
46
47 #[error(transparent)]
49 JSON(#[from] serde_json::Error),
50
51 #[error("could not parse {0:?} in a Docker action")]
53 ParseAction(String),
54
55 #[error(transparent)]
57 Reqwest(#[from] reqwest::Error),
58
59 #[error(transparent)]
61 VarError(#[from] std::env::VarError),
62}
63
64pub type Result<T> = std::result::Result<T, Error>;
66
67#[allow(dead_code)]
68pub(crate) fn exit_status_error(exit_status: &ExitStatus) -> Result<()> {
69 match exit_status.success() {
70 true => Ok(()),
71 false => {
72 match exit_status.code() {
73 Some(code) => {
74 Err(Error::ExitStatus(format!(
75 "Process terminated with exit code: {code}"
76 )))
77 },
78 None => {
79 Err(Error::ExitStatus(
80 "Process terminated by signal".to_string(),
81 ))
82 },
83 }
84 },
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use assert_matches::assert_matches;
91
92 use crate::error::Error;
93 #[cfg(feature = "cli")]
94 use clap::Command;
95
96 #[cfg(feature = "cli")]
97 #[test]
98 fn test_error_cli() {
99 let result =
100 Command::new("").try_get_matches_from(vec!["some", "args", "that", "should", "fail"]);
101 assert!(result.is_err());
102
103 let error: Error = result.unwrap_err().into();
104
105 assert_matches!(error, Error::Cli(_));
106 }
107
108 #[test]
109 fn test_error_json() {
110 let result = serde_json::from_str::<serde_json::Value>("invalid JSON");
111 assert!(result.is_err());
112
113 let error: Error = result.unwrap_err().into();
114
115 assert_matches!(error, Error::JSON(_));
116 }
117
118 #[test]
119 fn test_error_io() {
120 let result = std::fs::read_to_string("");
121 assert!(result.is_err());
122
123 let error: Error = result.unwrap_err().into();
124
125 assert_matches!(error, Error::IO(_));
126 }
127
128 #[test]
129 fn test_error_invalid_request() {
130 let result = crate::api::check::Request::new().try_get_text();
131 assert!(result.is_err());
132
133 let error: Error = result.unwrap_err().into();
134
135 assert_matches!(error, Error::InvalidRequest(_));
136 }
137
138 #[test]
139 fn test_error_invalid_value() {
140 let result = crate::api::server::parse_port("test");
141 assert!(result.is_err());
142
143 let error: Error = result.unwrap_err().into();
144
145 assert_matches!(error, Error::InvalidValue(_));
146 }
147
148 #[tokio::test]
149 async fn test_error_reqwest() {
150 let result = reqwest::get("").await;
151 let error: Error = result.unwrap_err().into();
152
153 assert_matches!(error, Error::Reqwest(_));
154 }
155}