questdb/error.rs
1/*******************************************************************************
2 * ___ _ ____ ____
3 * / _ \ _ _ ___ ___| |_| _ \| __ )
4 * | | | | | | |/ _ \/ __| __| | | | _ \
5 * | |_| | |_| | __/\__ \ |_| |_| | |_) |
6 * \__\_\\__,_|\___||___/\__|____/|____/
7 *
8 * Copyright (c) 2014-2019 Appsicle
9 * Copyright (c) 2019-2025 QuestDB
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 *
23 ******************************************************************************/
24use std::convert::Infallible;
25use std::fmt::{Display, Formatter};
26
27macro_rules! fmt {
28 ($code:ident, $($arg:tt)*) => {
29 crate::error::Error::new(
30 crate::error::ErrorCode::$code,
31 format!($($arg)*))
32 }
33}
34
35/// Category of error.
36///
37/// Accessible via Error's [`code`](Error::code) method.
38#[derive(Debug, Copy, Clone, PartialEq)]
39pub enum ErrorCode {
40 /// The host, port, or interface was incorrect.
41 CouldNotResolveAddr,
42
43 /// Called methods in the wrong order. E.g. `symbol` after `column`.
44 InvalidApiCall,
45
46 /// A network error connecting or flushing data out.
47 SocketError,
48
49 /// The string or symbol field is not encoded in valid UTF-8.
50 ///
51 /// *This error is reserved for the
52 /// [C and C++ API](https://github.com/questdb/c-questdb-client/).*
53 InvalidUtf8,
54
55 /// The table name or column name contains bad characters.
56 InvalidName,
57
58 /// The supplied timestamp is invalid.
59 InvalidTimestamp,
60
61 /// Error during the authentication process.
62 AuthError,
63
64 /// Error during TLS handshake.
65 TlsError,
66
67 /// The server does not support ILP-over-HTTP.
68 HttpNotSupported,
69
70 /// Error sent back from the server during flush.
71 ServerFlushError,
72
73 /// Bad configuration.
74 ConfigError,
75
76 /// There was an error serializing an array.
77 ArrayError,
78
79 /// Validate protocol version error.
80 ProtocolVersionError,
81}
82
83/// An error that occurred when using QuestDB client library.
84#[derive(Debug, PartialEq)]
85pub struct Error {
86 code: ErrorCode,
87 msg: String,
88}
89
90impl Error {
91 /// Create an error with the given code and message.
92 pub fn new<S: Into<String>>(code: ErrorCode, msg: S) -> Error {
93 Error {
94 code,
95 msg: msg.into(),
96 }
97 }
98
99 #[cfg(feature = "sync-sender-http")]
100 pub(crate) fn from_ureq_error(err: ureq::Error, url: &str) -> Error {
101 match err {
102 ureq::Error::StatusCode(code) => {
103 if code == 404 {
104 fmt!(
105 HttpNotSupported,
106 "Could not flush buffer: HTTP endpoint does not support ILP."
107 )
108 } else if [401, 403].contains(&code) {
109 fmt!(
110 AuthError,
111 "Could not flush buffer: HTTP endpoint authentication error [code: {}]",
112 code
113 )
114 } else {
115 fmt!(SocketError, "Could not flush buffer: {}: {}", url, err)
116 }
117 }
118 e => {
119 fmt!(SocketError, "Could not flush buffer: {}: {}", url, e)
120 }
121 }
122 }
123
124 /// Get the error code (category) of this error.
125 pub fn code(&self) -> ErrorCode {
126 self.code
127 }
128
129 /// Get the string message of this error.
130 pub fn msg(&self) -> &str {
131 &self.msg
132 }
133}
134
135impl Display for Error {
136 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
137 f.write_str(&self.msg)
138 }
139}
140
141impl std::error::Error for Error {}
142
143impl From<Infallible> for Error {
144 fn from(_: Infallible) -> Self {
145 unreachable!()
146 }
147}
148
149/// A specialized `Result` type for the crate's [`Error`] type.
150pub type Result<T> = std::result::Result<T, Error>;
151
152pub(crate) use fmt;