cfn_guard/rules/
errors.rs1use std::convert::Infallible;
2use std::fmt::{Debug, Formatter};
3use std::string::FromUtf8Error;
4use thiserror::Error;
5use wasm_bindgen::JsValue;
6
7use crate::rules::parser::{ParserError, Span};
8
9#[derive(Debug, Error)]
10#[allow(clippy::enum_variant_names)]
11pub enum Error {
12 #[error("Error parsing incoming JSON context {0}")]
13 JsonError(#[from] serde_json::Error),
14 #[error("Error parsing incoming YAML context {0}")]
15 YamlError(#[from] serde_yaml::Error),
16 #[error("Formatting error when writing {0}")]
17 FormatError(#[from] std::fmt::Error),
18 #[error("I/O error when reading {0}")]
19 IoError(#[from] std::io::Error),
20 #[error("Parser Error when parsing `{0}`")]
21 ParseError(String),
22 #[error("Regex expression parse error for rules file {0}")]
23 RegexError(#[from] Box<fancy_regex::Error>),
24 #[error(
25 "Could not evaluate clause for a rule with missing property for incoming context `{0}`"
26 )]
27 MissingProperty(String),
28 #[error("There was no variable or value object to resolve. Error = `{0}`")]
29 MissingValue(String),
30 #[error("Could not retrieve data from incoming context. Error = `{0}`")]
31 RetrievalError(String),
32 #[error("Variable assignment could not be resolved in rule file or incoming context `{0}`")]
33 MissingVariable(String),
34 #[error("Conflicting rule or variable assignments inside the same scope `{0}`")]
35 MultipleValues(String),
36 #[error("Types or variable assignments have incompatible types to retrieve `{0}`")]
37 IncompatibleRetrievalError(String),
38 #[error("Types or variable assignments are incompatible `{0}`")]
39 IncompatibleError(String),
40 #[error("Comparing incoming context with literals or dynamic results wasn't possible `{0}`")]
41 NotComparable(String),
42 #[error("Could not convert in JSON value object {0}")]
43 ConversionError(#[from] Infallible),
44 #[error("The path `{0}` does not exist")]
45 FileNotFoundError(String),
46 #[error(transparent)]
47 Errors(#[from] Errors),
48 #[error("{0}")]
49 IllegalArguments(String),
50 #[error("Error occurred while attempting to write junit report")]
51 XMLError(#[from] quick_xml::Error),
52 #[error("{0}")]
53 InternalError(#[from] InternalError),
54}
55
56#[derive(Debug, Error)]
57pub enum InternalError {
58 #[error("non string type detected for key in a map at {0}, cfn-guard only supports keys that are string types")]
59 InvalidKeyType(String),
60 #[error("internal error {0}")]
61 UnresolvedKeyForReporter(String),
62 #[error("{0}")]
63 FromUtf8Error(#[from] FromUtf8Error),
64 #[error("{0}")]
65 IncompatibleWriterError(String),
66 #[error("{0}")]
67 UnsupportedBufferError(String),
68 #[error("{0}")]
69 UnsupportedOperationError(String),
70}
71
72#[derive(Debug, Error)]
73pub struct Errors(pub Vec<Error>);
74
75impl std::fmt::Display for Errors {
76 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
77 let vec = self
78 .0
79 .iter()
80 .map(|e| format!("{e:#?}"))
81 .collect::<Vec<String>>();
82
83 let formatted = format!("{:?}", &vec);
84 write!(f, "{}", formatted)
85 }
86}
87
88impl<'a> From<nom::Err<(Span<'a>, nom::error::ErrorKind)>> for Error {
89 fn from(err: nom::Err<(Span<'a>, nom::error::ErrorKind)>) -> Self {
90 let msg = match err {
91 nom::Err::Incomplete(_) => "More bytes required for parsing".to_string(),
92 nom::Err::Failure((s, _k)) | nom::Err::Error((s, _k)) => {
93 let span = s as Span;
94 format!(
95 "Error parsing file {} at line {} at column {}, remaining {}",
96 span.extra,
97 span.location_line(),
98 span.get_utf8_column(),
99 *span.fragment()
100 )
101 }
102 };
103 Error::ParseError(msg)
104 }
105}
106
107impl<'a> From<nom::Err<ParserError<'a>>> for Error {
108 fn from(err: nom::Err<ParserError<'a>>) -> Self {
109 let msg = match err {
110 nom::Err::Failure(e) | nom::Err::Error(e) => format!("Parsing Error {e}"),
111 nom::Err::Incomplete(_) => "More bytes required for parsing".to_string(),
112 };
113 Error::ParseError(msg)
114 }
115}
116
117impl From<JsValue> for Error {
118 fn from(err: JsValue) -> Self {
119 err.into()
120 }
121}