scratch_test_model/aux/errors.rs
1use crate::aux::{AttrLocation, JsonCtx};
2
3/// General block parsing failed because of the json structure, this is not about [attributes](`crate::attrs`).
4#[derive(Debug, PartialEq, Clone, thiserror::Error)]
5pub enum BlockJsonStructureError {
6 /// The requested block [`Id`](`crate::Id`) wasn't found in the
7 /// [target](`crate::scopes::Target`)'s json mapping `blocks`
8 ///
9 /// This should rarely occur as multiple program parts only request blocks
10 /// that were previously found in the file by e. g. iterating over all
11 /// block `Id`s
12 #[error("the requested id doesn't exist in the current target")]
13 IdNotFound,
14 /// The found block data (for the requested [`Id`](`crate::Id`)) is not
15 /// a json mapping (`{ ... }`). This should never happen in a valid file.
16 #[error("block is not a json object/mapping, fields not found")]
17 BlockIsNoMapping,
18 /// Mapping is missing a needed key-value-pair, like `inputs` or `fields`.
19 ///
20 /// Regardless of the block's kind or opcode, some attributes need to be present.
21 /// Examples of such attributes are `opcode` or `inputs`.
22 /// For procedures the `mutation` key has to be present additionally.
23 #[error("block mapping doesn't contain mandatory '{0}' option")]
24 MissingMandatoryAttr(&'static str),
25 /// A block property is of invalid form, this is not about attributes like in [`crate::attrs`].
26 ///
27 /// `inputs`, `fields` and `mutation` need to be – if present – json mappings from
28 /// attribute names to their values. An opcode should be a string. This error
29 /// indicates that one of those expectations was violated.
30 #[error("the '{attr}' attribute is of the wrong type, it should be {correct_type}")]
31 AttrWrongType {
32 attr: &'static str,
33 correct_type: &'static str,
34 },
35}
36
37/// Specific error for the current block kind's requirements.
38///
39/// The most interesting one is [BlockKindError::AttrParsing] as this is produced
40/// by individual block attributes (the data associated with a particular block).
41#[derive(Debug, PartialEq, Clone, thiserror::Error)]
42pub enum BlockKindError<'a> {
43 /// The found opcode is no valid choice for the tried block kind.
44 ///
45 /// Either the wrong kind type was tried, the block opcode is not supported or it is
46 /// just invalid. Every opcode that is supported by a variant of
47 /// [`BlockKind`](crate::blocks::BlockKind) is valid.
48 #[error("the found opcode is no valid choice for the tried block kind: {0}")]
49 UnknownOpcode(svalue::ARc<str>),
50 #[error("json-repr of block: {0}")]
51 JsonStructure(#[from] BlockJsonStructureError),
52 #[error("missing block attr: {0}")]
53 MissingMandatoryAttr(#[from] MandatoryAttrMissingError),
54 #[error("parsing attribute {location}.'{key}': {error}")]
55 AttrParsing {
56 location: AttrLocation,
57 key: &'static str,
58 error: AttributeParseError<'a>,
59 },
60}
61
62/// Inner error indicating an attribute's content is invalid.
63///
64/// This is typically wrapped by [`AttributeParseError`] and focuses
65/// on errors of the type-specific format, when shadow information is
66/// already resolved.
67#[derive(derive_more::Debug, PartialEq, Clone, thiserror::Error)]
68pub enum AttributeContentError<'a> {
69 // Custom-Assoc-Type? / Subblock für alle?
70 #[error("{0}")]
71 #[debug("{_0:?}")]
72 Other(&'static str),
73
74 /// Some attributes can be one of multiple types. This is represented with [`either::Either`].
75 /// If the `Left` variant fails to parse, `Right` is tried with the same input.
76 /// If both fail the errors are returned.
77 #[error("'Either' attribute failed twice: first={first_err}, second={second_err}")]
78 BothEitherFailed {
79 first_err: Box<AttributeContentError<'a>>,
80 second_err: Box<AttributeContentError<'a>>,
81 },
82
83 #[error("expected an array (fixed-len={specified_length:?}): {value}")]
84 ExpectedArray {
85 value: &'a serde_json::Value,
86 specified_length: Option<usize>,
87 },
88
89 /// The found value is invalid, some attribute types provide a list with valid
90 /// alternatives/hints.
91 #[error("value {invalid:?} is invalid for dropdown, valid examples/hints: {hint_list}")]
92 InvalidOptionForDropdown {
93 invalid: String,
94 hint_list: &'static str,
95 },
96
97 #[error("this dropdown is expected to have a string id as reference to it's menu, not: {0}")]
98 ExternalDropdownMenuReferenceNotString(&'a serde_json::Value),
99
100 /// Some attributes don't contain the real data but only a reference to another block.
101 /// This variant means that such a block occured and wasn't totally valid.
102 #[error("there was an error parsing an indirection subblock: {0}")]
103 Subblock(Box<JsonCtx<'a, BlockKindError<'a>>>),
104}
105
106/// Main error for parsing of attributes.
107#[derive(Debug, PartialEq, Clone, thiserror::Error)]
108pub enum AttributeParseError<'a> {
109 /// The attribute's only value is a singleton array indicating that it contains shadow
110 /// information, but the array has no real data
111 #[error("attribute is not providing a real value, only shadow indication")]
112 ShadowWithoutValue,
113 /// The attribute has two nested shadow levels,
114 /// when the first is traversed (to the block hiding the possible shadow)
115 /// another shadow information was found. This is invalid
116 #[error("attribute contains two levels of shadow information, only one allowed")]
117 DuplicateShadow,
118 /// The attribute's value is invalid for the expected type.
119 #[error("content, shadowing={shadow_resolved}: {error}")]
120 Content {
121 /// If there was shadow information that was traversed to parse only the active value
122 ///
123 /// This can be useful to spot if an invalid value triggered shadow-resolving,
124 /// even though it shouldn't happen
125 shadow_resolved: bool,
126 /// The details about the error the content produced
127 error: AttributeContentError<'a>,
128 },
129}
130
131/// A mapping like `inputs` or `fields` misses an [attribute](`crate::attrs`) that is expected for the opcode.
132#[derive(Debug, PartialEq, PartialOrd, Clone, thiserror::Error)]
133#[error(
134 "the mandatory block attribute '{key}' is missing from the expected property set '{location}'"
135)]
136pub struct MandatoryAttrMissingError {
137 pub(super) location: AttrLocation,
138 pub(super) key: &'static str,
139}