Skip to content

Commit 7a19f34

Browse files
aw-server: Add Into trait for DatastoreError to HttpErrorJson
1 parent d985c51 commit 7a19f34

File tree

7 files changed

+110
-216
lines changed

7 files changed

+110
-216
lines changed

aw-datastore/src/worker.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ impl fmt::Debug for Datastore {
3939
* TODO:
4040
* - Allow read requests to go straight through a read-only db connection instead of requesting the
4141
* worker thread for better performance?
42+
* TODO: Add an seperate "Import" request which does an import with an transaction
4243
*/
4344

4445
#[allow(clippy::large_enum_variant)]

aw-server/src/endpoints/bucket.rs

Lines changed: 11 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,14 @@ use rocket::State;
1717

1818
use crate::endpoints::{HttpErrorJson, ServerState};
1919

20-
use aw_datastore::DatastoreError;
21-
2220
#[get("/")]
2321
pub fn buckets_get(
2422
state: State<ServerState>,
2523
) -> Result<Json<HashMap<String, Bucket>>, HttpErrorJson> {
2624
let datastore = endpoints_get_lock!(state.datastore);
2725
match datastore.get_buckets() {
2826
Ok(bucketlist) => Ok(Json(bucketlist)),
29-
Err(e) => {
30-
let err_msg = format!("Unexpected error: {:?}", e);
31-
warn!("{}", err_msg);
32-
Err(HttpErrorJson::new(Status::InternalServerError, err_msg))
33-
}
27+
Err(err) => Err(err.into()),
3428
}
3529
}
3630

@@ -42,17 +36,7 @@ pub fn bucket_get(
4236
let datastore = endpoints_get_lock!(state.datastore);
4337
match datastore.get_bucket(&bucket_id) {
4438
Ok(bucket) => Ok(Json(bucket)),
45-
Err(e) => match e {
46-
DatastoreError::NoSuchBucket => Err(HttpErrorJson::new(
47-
Status::NotFound,
48-
"The requested bucket does not exist".to_string(),
49-
)),
50-
_ => {
51-
let err_msg = format!("Unexpected error: {:?}", e);
52-
warn!("{}", err_msg);
53-
Err(HttpErrorJson::new(Status::InternalServerError, err_msg))
54-
}
55-
},
39+
Err(e) => Err(e.into()),
5640
}
5741
}
5842

@@ -66,34 +50,11 @@ pub fn bucket_new(
6650
if bucket.id != bucket_id {
6751
bucket.id = bucket_id;
6852
}
69-
// Cannot re-use endpoints_get_lock!() here because it returns Err(Status) on failure and this
70-
// function returns a Response
71-
let datastore = match state.datastore.lock() {
72-
Ok(ds) => ds,
73-
Err(e) => {
74-
warn!("Taking datastore lock failed, returning 504: {}", e);
75-
return Err(HttpErrorJson::new(
76-
Status::ServiceUnavailable,
77-
"Takind datastore lock failed".to_string(),
78-
));
79-
}
80-
};
53+
let datastore = endpoints_get_lock!(state.datastore);
8154
let ret = datastore.create_bucket(&bucket);
8255
match ret {
8356
Ok(_) => Ok(()),
84-
Err(err) => match err {
85-
DatastoreError::BucketAlreadyExists => Err(HttpErrorJson::new(
86-
Status::NotModified,
87-
"Bucket already exists".to_string(),
88-
)),
89-
_ => {
90-
warn!("Unexpected error: {:?}", err);
91-
Err(HttpErrorJson::new(
92-
Status::InternalServerError,
93-
format!("{:?}", err),
94-
))
95-
}
96-
},
57+
Err(err) => Err(err.into()),
9758
}
9859
}
9960

@@ -137,17 +98,7 @@ pub fn bucket_events_get(
13798
let res = datastore.get_events(&bucket_id, starttime, endtime, limit);
13899
match res {
139100
Ok(events) => Ok(Json(events)),
140-
Err(err) => match err {
141-
DatastoreError::NoSuchBucket => Err(HttpErrorJson::new(
142-
Status::NotFound,
143-
"The requested bucket does not exist".to_string(),
144-
)),
145-
e => {
146-
let err_msg = format!("Failed to fetch events: {:?}", e);
147-
warn!("{}", err_msg);
148-
Err(HttpErrorJson::new(Status::InternalServerError, err_msg))
149-
}
150-
},
101+
Err(err) => Err(err.into()),
151102
}
152103
}
153104

@@ -161,17 +112,7 @@ pub fn bucket_events_create(
161112
let res = datastore.insert_events(&bucket_id, &events);
162113
match res {
163114
Ok(events) => Ok(Json(events)),
164-
Err(e) => match e {
165-
DatastoreError::NoSuchBucket => Err(HttpErrorJson::new(
166-
Status::NotFound,
167-
"The requested bucket does not exist".to_string(),
168-
)),
169-
e => {
170-
let err_msg = format!("Failed to create event(s): {:?}", e);
171-
warn!("{}", err_msg);
172-
Err(HttpErrorJson::new(Status::InternalServerError, err_msg))
173-
}
174-
},
115+
Err(err) => Err(err.into()),
175116
}
176117
}
177118

@@ -190,17 +131,7 @@ pub fn bucket_events_heartbeat(
190131
let datastore = endpoints_get_lock!(state.datastore);
191132
match datastore.heartbeat(&bucket_id, heartbeat, pulsetime) {
192133
Ok(e) => Ok(Json(e)),
193-
Err(err) => match err {
194-
DatastoreError::NoSuchBucket => Err(HttpErrorJson::new(
195-
Status::NotFound,
196-
"The requested bucket does not exist".to_string(),
197-
)),
198-
err => {
199-
let err_msg = format!("Heartbeat failed: {:?}", err);
200-
warn!("{}", err_msg);
201-
Err(HttpErrorJson::new(Status::InternalServerError, err_msg))
202-
}
203-
},
134+
Err(err) => Err(err.into()),
204135
}
205136
}
206137

@@ -213,17 +144,7 @@ pub fn bucket_event_count(
213144
let res = datastore.get_event_count(&bucket_id, None, None);
214145
match res {
215146
Ok(eventcount) => Ok(Json(eventcount as u64)),
216-
Err(e) => match e {
217-
DatastoreError::NoSuchBucket => Err(HttpErrorJson::new(
218-
Status::NotFound,
219-
"The requested bucket does not exist".to_string(),
220-
)),
221-
e => {
222-
let err_msg = format!("Failed to count events: {:?}", e);
223-
warn!("{}", err_msg);
224-
Err(HttpErrorJson::new(Status::InternalServerError, err_msg))
225-
}
226-
},
147+
Err(err) => Err(err.into()),
227148
}
228149
}
229150

@@ -236,17 +157,7 @@ pub fn bucket_events_delete_by_id(
236157
let datastore = endpoints_get_lock!(state.datastore);
237158
match datastore.delete_events_by_id(&bucket_id, vec![event_id]) {
238159
Ok(_) => Ok(()),
239-
Err(err) => match err {
240-
DatastoreError::NoSuchBucket => Err(HttpErrorJson::new(
241-
Status::NotFound,
242-
"The requested bucket does not exist".to_string(),
243-
)),
244-
err => {
245-
let err_msg = format!("Delete events by id failed: {:?}", err);
246-
warn!("{}", err_msg);
247-
Err(HttpErrorJson::new(Status::InternalServerError, err_msg))
248-
}
249-
},
160+
Err(err) => Err(err.into()),
250161
}
251162
}
252163

@@ -261,19 +172,7 @@ pub fn bucket_export(
261172
};
262173
let mut bucket = match datastore.get_bucket(&bucket_id) {
263174
Ok(bucket) => bucket,
264-
Err(err) => match err {
265-
DatastoreError::NoSuchBucket => {
266-
return Err(HttpErrorJson::new(
267-
Status::NotFound,
268-
"The requested bucket does not exist".to_string(),
269-
))
270-
}
271-
e => {
272-
let err_msg = format!("Failed to fetch events: {:?}", e);
273-
warn!("{}", err_msg);
274-
return Err(HttpErrorJson::new(Status::InternalServerError, err_msg));
275-
}
276-
},
175+
Err(err) => return Err(err.into()),
277176
};
278177
bucket.events = Some(
279178
datastore
@@ -298,16 +197,6 @@ pub fn bucket_delete(bucket_id: String, state: State<ServerState>) -> Result<(),
298197
let datastore = endpoints_get_lock!(state.datastore);
299198
match datastore.delete_bucket(&bucket_id) {
300199
Ok(_) => Ok(()),
301-
Err(e) => match e {
302-
DatastoreError::NoSuchBucket => Err(HttpErrorJson::new(
303-
Status::NotFound,
304-
"The requested bucket does not exist".to_string(),
305-
)),
306-
e => {
307-
let err_msg = format!("Failed to delete bucket: {:?}", e);
308-
warn!("{}", err_msg);
309-
Err(HttpErrorJson::new(Status::InternalServerError, err_msg))
310-
}
311-
},
200+
Err(err) => Err(err.into()),
312201
}
313202
}

aw-server/src/endpoints/export.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ pub fn buckets_export(state: State<ServerState>) -> Result<Response, HttpErrorJs
1616
let mut export = BucketsExport {
1717
buckets: HashMap::new(),
1818
};
19-
let mut buckets = datastore.get_buckets().unwrap();
19+
let mut buckets = match datastore.get_buckets() {
20+
Ok(buckets) => buckets,
21+
Err(err) => return Err(err.into()),
22+
};
2023
for (bid, mut bucket) in buckets.drain() {
21-
bucket.events = Some(
22-
// TODO: Remove expect
23-
datastore
24-
.get_events(&bid, None, None, None)
25-
.expect("Failed to get events for bucket"),
26-
);
24+
bucket.events = Some(match datastore.get_events(&bid, None, None, None) {
25+
Ok(events) => events,
26+
Err(err) => return Err(err.into()),
27+
});
2728
export.buckets.insert(bid, bucket);
2829
}
2930

aw-server/src/endpoints/mod.rs

Lines changed: 4 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use std::path::PathBuf;
22
use std::sync::Mutex;
33

44
use gethostname::gethostname;
5-
use rocket::http::Status;
65
use rocket::response::NamedFile;
76
use rocket::State;
87
use rocket_contrib::json::JsonValue;
@@ -17,58 +16,17 @@ pub struct ServerState {
1716
pub device_id: String,
1817
}
1918

20-
use rocket::http::ContentType;
21-
use rocket::request::Request;
22-
use rocket::response::{self, Responder, Response};
23-
use std::io::Cursor;
24-
25-
#[derive(Serialize, Debug)]
26-
pub struct HttpErrorJson {
27-
#[serde(skip_serializing)]
28-
status: Status,
29-
message: String,
30-
}
31-
32-
impl HttpErrorJson {
33-
pub fn new(status: Status, err: String) -> HttpErrorJson {
34-
HttpErrorJson {
35-
status: status,
36-
message: format!("{}", err),
37-
}
38-
}
39-
}
40-
41-
impl<'r> Responder<'r> for HttpErrorJson {
42-
fn respond_to(self, _: &Request) -> response::Result<'r> {
43-
Response::build()
44-
.status(self.status)
45-
.sized_body(Cursor::new(format!("{{\"message\":\"{}\"}}", self.message)))
46-
.header(ContentType::new("application", "json"))
47-
.ok()
48-
}
49-
}
50-
51-
#[macro_export]
52-
macro_rules! endpoints_get_lock {
53-
( $lock:expr ) => {
54-
match $lock.lock() {
55-
Ok(r) => r,
56-
Err(e) => {
57-
let err_msg = format!("Taking datastore lock failed, returning 504: {}", e);
58-
warn!("{}", err_msg);
59-
return Err(HttpErrorJson::new(Status::ServiceUnavailable, err_msg));
60-
}
61-
}
62-
};
63-
}
64-
19+
#[macro_use]
20+
mod util;
6521
mod bucket;
6622
mod cors;
6723
mod export;
6824
mod import;
6925
mod query;
7026
mod settings;
7127

28+
pub use util::HttpErrorJson;
29+
7230
#[get("/")]
7331
fn root_index(state: State<ServerState>) -> Option<NamedFile> {
7432
NamedFile::open(state.asset_path.join("index.html")).ok()

aw-server/src/endpoints/query.rs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,8 @@ pub fn query(
1414
let query_code = query_req.0.query.join("\n");
1515
let intervals = &query_req.0.timeperiods;
1616
let mut results = Vec::new();
17+
let datastore = endpoints_get_lock!(state.datastore);
1718
for interval in intervals {
18-
// Cannot re-use endpoints_get_lock!() here because it returns Err(Status) on failure and this
19-
// function returns HttpResponse
20-
let datastore = match state.datastore.lock() {
21-
Ok(ds) => ds,
22-
Err(e) => {
23-
warn!("Taking datastore lock failed, returning 500: {}", e);
24-
return Err(HttpErrorJson::new(
25-
Status::ServiceUnavailable,
26-
"Taking datastore lock failed, see aw-server logs".to_string(),
27-
));
28-
}
29-
};
3019
let result = match aw_query::query(&query_code, &interval, &datastore) {
3120
Ok(data) => data,
3221
Err(e) => {

0 commit comments

Comments
 (0)