Skip to main content

cli/data/import_v2/
error.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use 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}