Skip to main content

risingwave_meta/hummock/
error.rs

1// Copyright 2022 RisingWave Labs
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 risingwave_common::catalog::TableId;
16use risingwave_hummock_sdk::{HummockContextId, HummockSstableObjectId};
17use risingwave_object_store::object::ObjectError;
18use risingwave_rpc_client::error::ToTonicStatus;
19use sea_orm::DbErr;
20use thiserror::Error;
21
22use crate::model::MetadataModelError;
23
24pub type Result<T> = std::result::Result<T, Error>;
25
26#[derive(Error, Debug)]
27pub enum Error {
28    #[error("invalid hummock context {0}")]
29    InvalidContext(HummockContextId),
30    #[error("failed to access meta store")]
31    MetaStore(
32        #[source]
33        #[backtrace]
34        anyhow::Error,
35    ),
36    #[error(transparent)]
37    ObjectStore(
38        #[from]
39        #[backtrace]
40        ObjectError,
41    ),
42    #[error("compactor {0} is disconnected")]
43    CompactorUnreachable(HummockContextId),
44    #[error("compaction group error: {0}")]
45    CompactionGroup(String),
46    #[error("SST {0} is invalid")]
47    InvalidSst(HummockSstableObjectId),
48    #[error("invalid manual compaction option: {0}")]
49    InvalidManualCompactionOption(String),
50    #[error("invalid epoch range: {start_epoch}..={end_epoch}")]
51    InvalidEpochRange { start_epoch: u64, end_epoch: u64 },
52    #[error("time-travel version expired: table {table_id}, epoch {epoch}")]
53    TimeTravelVersionExpired { table_id: TableId, epoch: u64 },
54    #[error("time travel")]
55    TimeTravel(
56        #[source]
57        #[backtrace]
58        anyhow::Error,
59    ),
60    #[error(transparent)]
61    Internal(
62        #[from]
63        #[backtrace]
64        anyhow::Error,
65    ),
66}
67
68impl Error {
69    pub fn retryable(&self) -> bool {
70        matches!(self, Error::MetaStore(_))
71    }
72}
73
74impl From<MetadataModelError> for Error {
75    fn from(err: MetadataModelError) -> Self {
76        anyhow::anyhow!(err).into()
77    }
78}
79
80impl From<sea_orm::DbErr> for Error {
81    fn from(value: DbErr) -> Self {
82        MetadataModelError::from(value).into()
83    }
84}
85
86impl From<Error> for tonic::Status {
87    fn from(err: Error) -> Self {
88        let code = match &err {
89            Error::InvalidManualCompactionOption(_) | Error::InvalidEpochRange { .. } => {
90                tonic::Code::InvalidArgument
91            }
92            Error::TimeTravelVersionExpired { .. } => tonic::Code::OutOfRange,
93            _ => tonic::Code::Internal,
94        };
95        err.to_status(code, "hummock")
96    }
97}