1use crate::awl::{AWL_DOCUMENT_PREFIX, AWL_SCHEMA_PREFIX};
4
5#[derive(thiserror::Error, Debug)]
7pub enum PackageError {
8 #[error("failed to read .aion ZIP archive: {0}")]
10 ArchiveRead(#[from] zip::result::ZipError),
11
12 #[error("missing required manifest.json entry")]
14 MissingManifest,
15
16 #[error("missing required contract record for .v4 package identity")]
18 MissingContractRecord,
19
20 #[error(
22 "module `{module}` uses an engine-reserved namespace and must not ship as package bytecode"
23 )]
24 ReservedModuleName {
25 module: String,
27 },
28
29 #[error("failed to write .aion ZIP archive: {0}")]
31 ArchiveWrite(zip::result::ZipError),
32
33 #[error("failed to write .aion archive bytes: {source}")]
35 ArchiveWriteIo {
36 source: std::io::Error,
38 },
39
40 #[error("failed to parse manifest.json: {source}")]
42 ManifestParse {
43 source: serde_json::Error,
45 },
46
47 #[error("failed to serialise manifest.json: {source}")]
49 ManifestSerialise {
50 source: serde_json::Error,
52 },
53
54 #[error("failed to parse contract.json: {source}")]
56 ContractParse {
57 source: serde_json::Error,
59 },
60
61 #[error("failed to serialise contract.json: {source}")]
63 ContractSerialise {
64 source: serde_json::Error,
66 },
67
68 #[error("unknown .aion format_version {found}")]
70 UnknownFormatVersion {
71 found: u32,
73 },
74
75 #[error("missing entry module `{module}` in beam set")]
77 MissingEntryModule {
78 module: String,
80 },
81
82 #[error("package integrity mismatch: expected version `{expected}`, computed `{computed}`")]
84 IntegrityMismatch {
85 expected: String,
87 computed: String,
89 },
90
91 #[error("malformed beam entry `{entry}`")]
93 MalformedBeamEntry {
94 entry: String,
96 },
97
98 #[error("malformed AWL source entry `{entry}`")]
101 MalformedAwlEntry {
102 entry: String,
104 },
105
106 #[error("archived AWL document `{entry}` is not valid UTF-8: {source}")]
108 AwlDocumentNotUtf8 {
109 entry: String,
111 source: std::string::FromUtf8Error,
113 },
114
115 #[error("archive carries `{AWL_SCHEMA_PREFIX}` entries but no `{AWL_DOCUMENT_PREFIX}` entry")]
118 MissingAwlDocument,
119
120 #[error(
122 "archive contents inflate past the extraction limit of {limit} bytes; refusing to extract further"
123 )]
124 InflatedSizeExceeded {
125 limit: u64,
127 },
128}
129
130#[cfg(test)]
131mod tests {
132 use super::PackageError;
133
134 fn assert_send_sync<T: Send + Sync>() {}
135
136 #[test]
137 fn package_error_is_send_and_sync() {
138 assert_send_sync::<PackageError>();
139 }
140
141 #[test]
142 fn display_messages_name_the_failed_condition() {
143 assert_eq!(
144 PackageError::MissingManifest.to_string(),
145 "missing required manifest.json entry"
146 );
147 assert_eq!(
148 PackageError::ArchiveWriteIo {
149 source: std::io::Error::other("disk full"),
150 }
151 .to_string(),
152 "failed to write .aion archive bytes: disk full"
153 );
154 assert_eq!(
155 PackageError::UnknownFormatVersion { found: 99 }.to_string(),
156 "unknown .aion format_version 99"
157 );
158 assert_eq!(
159 PackageError::MissingEntryModule {
160 module: "workflow/main".to_owned(),
161 }
162 .to_string(),
163 "missing entry module `workflow/main` in beam set"
164 );
165 assert_eq!(
166 PackageError::IntegrityMismatch {
167 expected: "expected".to_owned(),
168 computed: "computed".to_owned(),
169 }
170 .to_string(),
171 "package integrity mismatch: expected version `expected`, computed `computed`"
172 );
173 assert_eq!(
174 PackageError::MalformedBeamEntry {
175 entry: "beam/workflow.beam".to_owned(),
176 }
177 .to_string(),
178 "malformed beam entry `beam/workflow.beam`"
179 );
180 assert_eq!(
181 PackageError::InflatedSizeExceeded { limit: 1024 }.to_string(),
182 "archive contents inflate past the extraction limit of 1024 bytes; refusing to extract further"
183 );
184 }
185}