Skip to content

Commit 9d8d453

Browse files
0xDmtriEmpty2k12
andauthored
Better Errors (#150)
* bump * error with an api status code * remove redundant import * fix ApiError * fix ApiError by converting StatusCode to u16 * revert * u16 as StatusCode * update tests * improve tests readability * fix: ci tests & add docker-compose local test harness --------- Co-authored-by: Gero Gerke <hello@gero.dev>
1 parent bfe457c commit 9d8d453

File tree

5 files changed

+65
-36
lines changed

5 files changed

+65
-36
lines changed

docker-compose.integrationtest.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
version: '3'
2+
services:
3+
influxdb:
4+
image: influxdb:1.8
5+
ports:
6+
- 8086:8086
7+
authed_influxdb:
8+
image: influxdb:1.8
9+
ports:
10+
- 9086:8086
11+
environment:
12+
INFLUXDB_HTTP_AUTH_ENABLED: true
13+
INFLUXDB_ADMIN_USER: admin
14+
INFLUXDB_ADMIN_PASSWORD: password
15+
INFLUXDB_USER: nopriv_user
16+
INFLUXDB_USER_PASSWORD: password
17+
influxdbv2:
18+
image: influxdb:2.6
19+
ports:
20+
- 2086:8086
21+
environment:
22+
DOCKER_INFLUXDB_INIT_MODE: setup
23+
DOCKER_INFLUXDB_INIT_USERNAME: admin
24+
DOCKER_INFLUXDB_INIT_PASSWORD: password
25+
DOCKER_INFLUXDB_INIT_ORG: testing
26+
DOCKER_INFLUXDB_INIT_BUCKET: mydb
27+
DOCKER_INFLUXDB_INIT_ADMIN_TOKEN: admintoken

influxdb/src/client/mod.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
//! ```
1717
1818
use futures_util::TryFutureExt;
19-
use http::StatusCode;
2019
#[cfg(feature = "reqwest")]
2120
use reqwest::{Client as HttpClient, RequestBuilder, Response as HttpResponse};
2221
use std::collections::{BTreeMap, HashMap};
@@ -281,7 +280,7 @@ impl Client {
281280
})?;
282281

283282
// todo: improve error parsing without serde
284-
if s.contains("\"error\"") {
283+
if s.contains("\"error\"") || s.contains("\"Error\"") {
285284
return Err(Error::DatabaseError {
286285
error: format!("influxdb error: \"{}\"", s),
287286
});
@@ -301,13 +300,10 @@ impl Client {
301300

302301
pub(crate) fn check_status(res: &HttpResponse) -> Result<(), Error> {
303302
let status = res.status();
304-
if status == StatusCode::UNAUTHORIZED.as_u16() {
305-
Err(Error::AuthorizationError)
306-
} else if status == StatusCode::FORBIDDEN.as_u16() {
307-
Err(Error::AuthenticationError)
308-
} else {
309-
Ok(())
303+
if !status.is_success() {
304+
return Err(Error::ApiError(status.into()));
310305
}
306+
Ok(())
311307
}
312308

313309
#[cfg(test)]

influxdb/src/error.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,9 @@ pub enum Error {
2525
/// Error which has happened inside InfluxDB
2626
DatabaseError { error: String },
2727

28-
#[error("authentication error. No or incorrect credentials")]
29-
/// Error happens when no or incorrect credentials are used. `HTTP 401 Unauthorized`
30-
AuthenticationError,
31-
32-
#[error("authorization error. User not authorized")]
33-
/// Error happens when the supplied user is not authorized. `HTTP 403 Forbidden`
34-
AuthorizationError,
28+
#[error("API error with a status code: {0}")]
29+
/// Error happens when API returns non 2xx status code.
30+
ApiError(u16),
3531

3632
#[error("connection error: {error}")]
3733
/// Error happens when HTTP request fails

influxdb/tests/integration_tests.rs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ async fn test_authed_write_and_read() {
120120
#[async_std::test]
121121
#[cfg(not(tarpaulin_include))]
122122
async fn test_wrong_authed_write_and_read() {
123+
use http::StatusCode;
124+
123125
const TEST_NAME: &str = "test_wrong_authed_write_and_read";
124126

125127
run_test(
@@ -140,9 +142,9 @@ async fn test_wrong_authed_write_and_read() {
140142
let write_result = client.query(write_query).await;
141143
assert_result_err(&write_result);
142144
match write_result {
143-
Err(Error::AuthorizationError) => {}
145+
Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}
144146
_ => panic!(
145-
"Should be an AuthorizationError: {}",
147+
"Should be an ApiError(UNAUTHORIZED): {}",
146148
write_result.unwrap_err()
147149
),
148150
}
@@ -151,9 +153,9 @@ async fn test_wrong_authed_write_and_read() {
151153
let read_result = client.query(read_query).await;
152154
assert_result_err(&read_result);
153155
match read_result {
154-
Err(Error::AuthorizationError) => {}
156+
Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}
155157
_ => panic!(
156-
"Should be an AuthorizationError: {}",
158+
"Should be an ApiError(UNAUTHORIZED): {}",
157159
read_result.unwrap_err()
158160
),
159161
}
@@ -164,9 +166,9 @@ async fn test_wrong_authed_write_and_read() {
164166
let read_result = client.query(read_query).await;
165167
assert_result_err(&read_result);
166168
match read_result {
167-
Err(Error::AuthenticationError) => {}
169+
Err(Error::ApiError(code)) if code == StatusCode::FORBIDDEN.as_u16() => {}
168170
_ => panic!(
169-
"Should be an AuthenticationError: {}",
171+
"Should be an ApiError(UNAUTHENTICATED): {}",
170172
read_result.unwrap_err()
171173
),
172174
}
@@ -190,6 +192,8 @@ async fn test_wrong_authed_write_and_read() {
190192
#[async_std::test]
191193
#[cfg(not(tarpaulin_include))]
192194
async fn test_non_authed_write_and_read() {
195+
use http::StatusCode;
196+
193197
const TEST_NAME: &str = "test_non_authed_write_and_read";
194198

195199
run_test(
@@ -208,9 +212,9 @@ async fn test_non_authed_write_and_read() {
208212
let write_result = non_authed_client.query(write_query).await;
209213
assert_result_err(&write_result);
210214
match write_result {
211-
Err(Error::AuthorizationError) => {}
215+
Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}
212216
_ => panic!(
213-
"Should be an AuthorizationError: {}",
217+
"Should be an ApiError(UNAUTHORIZED): {}",
214218
write_result.unwrap_err()
215219
),
216220
}
@@ -220,9 +224,9 @@ async fn test_non_authed_write_and_read() {
220224

221225
assert_result_err(&read_result);
222226
match read_result {
223-
Err(Error::AuthorizationError) => {}
227+
Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}
224228
_ => panic!(
225-
"Should be an AuthorizationError: {}",
229+
"Should be an ApiError(UNAUTHORIZED): {}",
226230
read_result.unwrap_err()
227231
),
228232
}
@@ -280,6 +284,8 @@ async fn test_write_and_read_field() {
280284
#[cfg(feature = "serde")]
281285
#[cfg(not(tarpaulin_include))]
282286
async fn test_json_non_authed_read() {
287+
use http::StatusCode;
288+
283289
const TEST_NAME: &str = "test_json_non_authed_read";
284290

285291
run_test(
@@ -297,9 +303,9 @@ async fn test_json_non_authed_read() {
297303
let read_result = non_authed_client.json_query(read_query).await;
298304
assert_result_err(&read_result);
299305
match read_result {
300-
Err(Error::AuthorizationError) => {}
306+
Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}
301307
_ => panic!(
302-
"Should be a AuthorizationError: {}",
308+
"Should be an ApiError(UNAUTHORIZED): {}",
303309
read_result.unwrap_err()
304310
),
305311
}

influxdb/tests/integration_tests_v2.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ async fn test_authed_write_and_read() {
3333
},
3434
|| async move {
3535
let client = Client::new("http://127.0.0.1:2086", "mydb").with_token("admintoken");
36-
let read_query = ReadQuery::new("DELETE MEASUREMENT weather");
36+
let read_query = ReadQuery::new("DROP MEASUREMENT \"weather\"");
3737
let read_result = client.query(read_query).await;
3838
assert_result_ok(&read_result);
3939
assert!(!read_result.unwrap().contains("error"), "Teardown failed");
@@ -48,6 +48,8 @@ async fn test_authed_write_and_read() {
4848
#[async_std::test]
4949
#[cfg(not(tarpaulin))]
5050
async fn test_wrong_authed_write_and_read() {
51+
use http::StatusCode;
52+
5153
run_test(
5254
|| async move {
5355
let client = Client::new("http://127.0.0.1:2086", "mydb").with_token("falsetoken");
@@ -57,9 +59,9 @@ async fn test_wrong_authed_write_and_read() {
5759
let write_result = client.query(&write_query).await;
5860
assert_result_err(&write_result);
5961
match write_result {
60-
Err(Error::AuthorizationError) => {}
62+
Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}
6163
_ => panic!(
62-
"Should be an AuthorizationError: {}",
64+
"Should be an ApiError(UNAUTHORIZED): {}",
6365
write_result.unwrap_err()
6466
),
6567
}
@@ -68,9 +70,9 @@ async fn test_wrong_authed_write_and_read() {
6870
let read_result = client.query(&read_query).await;
6971
assert_result_err(&read_result);
7072
match read_result {
71-
Err(Error::AuthorizationError) => {}
73+
Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}
7274
_ => panic!(
73-
"Should be an AuthorizationError: {}",
75+
"Should be an ApiError(UNAUTHORIZED): {}",
7476
read_result.unwrap_err()
7577
),
7678
}
@@ -86,6 +88,8 @@ async fn test_wrong_authed_write_and_read() {
8688
#[async_std::test]
8789
#[cfg(not(tarpaulin))]
8890
async fn test_non_authed_write_and_read() {
91+
use http::StatusCode;
92+
8993
run_test(
9094
|| async move {
9195
let non_authed_client = Client::new("http://127.0.0.1:2086", "mydb");
@@ -95,9 +99,9 @@ async fn test_non_authed_write_and_read() {
9599
let write_result = non_authed_client.query(&write_query).await;
96100
assert_result_err(&write_result);
97101
match write_result {
98-
Err(Error::AuthorizationError) => {}
102+
Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}
99103
_ => panic!(
100-
"Should be an AuthorizationError: {}",
104+
"Should be an ApiError(UNAUTHORIZED): {}",
101105
write_result.unwrap_err()
102106
),
103107
}
@@ -106,9 +110,9 @@ async fn test_non_authed_write_and_read() {
106110
let read_result = non_authed_client.query(&read_query).await;
107111
assert_result_err(&read_result);
108112
match read_result {
109-
Err(Error::AuthorizationError) => {}
113+
Err(Error::ApiError(code)) if code == StatusCode::UNAUTHORIZED.as_u16() => {}
110114
_ => panic!(
111-
"Should be an AuthorizationError: {}",
115+
"Should be an ApiError(UNAUTHORIZED): {}",
112116
read_result.unwrap_err()
113117
),
114118
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy