cli/data/import_v2/
error.rs1use std::any::Any;
16
17use common_error::ext::ErrorExt;
18use common_error::status_code::StatusCode;
19use common_macro::stack_trace_debug;
20use snafu::{Location, Snafu};
21
22use crate::data::export_v2::manifest::ChunkStatus;
23
24#[derive(Snafu)]
25#[snafu(visibility(pub))]
26#[stack_trace_debug]
27pub enum Error {
28 #[snafu(display("Snapshot not found at '{}'", uri))]
29 SnapshotNotFound {
30 uri: String,
31 #[snafu(implicit)]
32 location: Location,
33 },
34
35 #[snafu(display("Manifest version mismatch: expected {}, found {}", expected, found))]
36 ManifestVersionMismatch {
37 expected: u32,
38 found: u32,
39 #[snafu(implicit)]
40 location: Location,
41 },
42
43 #[snafu(display("Schema '{}' not found in snapshot", schema))]
44 SchemaNotInSnapshot {
45 schema: String,
46 #[snafu(implicit)]
47 location: Location,
48 },
49
50 #[snafu(display("Incomplete snapshot: chunk {} has status {:?}", chunk_id, status))]
51 IncompleteSnapshot {
52 chunk_id: u32,
53 status: ChunkStatus,
54 #[snafu(implicit)]
55 location: Location,
56 },
57
58 #[snafu(display(
59 "Snapshot is inconsistent: chunk {} is marked completed but its file manifest is empty",
60 chunk_id
61 ))]
62 EmptyChunkManifest {
63 chunk_id: u32,
64 #[snafu(implicit)]
65 location: Location,
66 },
67
68 #[snafu(display(
69 "Snapshot is inconsistent: chunk {} for schema '{}' is marked completed but no files were found under '{}'",
70 chunk_id,
71 schema,
72 path
73 ))]
74 MissingChunkData {
75 chunk_id: u32,
76 schema: String,
77 path: String,
78 #[snafu(implicit)]
79 location: Location,
80 },
81
82 #[snafu(display("Chunk {} import failed for schema '{}'", chunk_id, schema))]
83 ChunkImportFailed {
84 chunk_id: u32,
85 schema: String,
86 #[snafu(source)]
87 error: crate::data::export_v2::error::Error,
88 #[snafu(implicit)]
89 location: Location,
90 },
91
92 #[snafu(display("Snapshot storage error"))]
93 SnapshotStorage {
94 #[snafu(source)]
95 error: crate::data::export_v2::error::Error,
96 #[snafu(implicit)]
97 location: Location,
98 },
99
100 #[snafu(display("Database error"))]
101 Database {
102 #[snafu(source)]
103 error: crate::error::Error,
104 #[snafu(implicit)]
105 location: Location,
106 },
107
108 #[snafu(display("Failed to parse import state file"))]
109 ImportStateParse {
110 #[snafu(source)]
111 error: serde_json::Error,
112 #[snafu(implicit)]
113 location: Location,
114 },
115
116 #[snafu(display("Import state I/O failed at '{}': {}", path, error))]
117 ImportStateIo {
118 path: String,
119 #[snafu(source)]
120 error: std::io::Error,
121 #[snafu(implicit)]
122 location: Location,
123 },
124
125 #[snafu(display("Import state is already locked at '{}'", path))]
126 ImportStateLocked {
127 path: String,
128 #[snafu(implicit)]
129 location: Location,
130 },
131
132 #[snafu(display("Import state references unknown chunk {}", chunk_id))]
133 ImportStateUnknownChunk {
134 chunk_id: u32,
135 #[snafu(implicit)]
136 location: Location,
137 },
138}
139
140pub type Result<T> = std::result::Result<T, Error>;
141
142impl ErrorExt for Error {
143 fn status_code(&self) -> StatusCode {
144 match self {
145 Error::SnapshotNotFound { .. }
146 | Error::SchemaNotInSnapshot { .. }
147 | Error::ManifestVersionMismatch { .. }
148 | Error::IncompleteSnapshot { .. }
149 | Error::EmptyChunkManifest { .. }
150 | Error::MissingChunkData { .. } => StatusCode::InvalidArguments,
151 Error::ImportStateUnknownChunk { .. } => StatusCode::Unexpected,
152 Error::Database { error, .. } => error.status_code(),
153 Error::SnapshotStorage { error, .. } | Error::ChunkImportFailed { error, .. } => {
154 error.status_code()
155 }
156 Error::ImportStateParse { .. } => StatusCode::Internal,
157 Error::ImportStateIo { .. } => StatusCode::StorageUnavailable,
158 Error::ImportStateLocked { .. } => StatusCode::IllegalState,
159 }
160 }
161
162 fn as_any(&self) -> &dyn Any {
163 self
164 }
165}