diff options
author | fx <[email protected]> | 2023-10-09 17:26:59 +0200 |
---|---|---|
committer | fx <[email protected]> | 2023-10-09 17:26:59 +0200 |
commit | 3e6a72428824c5a50a873a4284b86d0a9e47a778 (patch) | |
tree | 7f3594f4068a8009210039bc33e0205a672828f7 | |
parent | 732c487d3dab4af9fc561527591d3d56299e39f2 (diff) | |
download | webol-3e6a72428824c5a50a873a4284b86d0a9e47a778.tar webol-3e6a72428824c5a50a873a4284b86d0a9e47a778.tar.gz webol-3e6a72428824c5a50a873a4284b86d0a9e47a778.zip |
db int for api
-rw-r--r-- | .env | 2 | ||||
-rw-r--r-- | .sqlx/query-3ed66b56b7e78a6b6bad9d49c49607520a8d09f902b996467dddf58737a3757f.json | 16 | ||||
-rw-r--r-- | .sqlx/query-6a81887a8b44b527ad04c8963d5186b764ec9125d597f9fba566e280bd09d352.json | 36 | ||||
-rw-r--r-- | .sqlx/query-bb9c6a42084b92c339a85f9b1c094959a49c6b7383f1a0b49df242e2720a9185.json (renamed from .sqlx/query-035eea2a3ffbc6fcf5e1646f4e13e879b6e13325e38cd10d5ee160c5aded2caf.json) | 16 | ||||
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | docker-compose.yml | 11 | ||||
-rw-r--r-- | src/db.rs | 3 | ||||
-rw-r--r-- | src/error.rs | 31 | ||||
-rw-r--r-- | src/main.rs | 35 | ||||
-rw-r--r-- | src/routes/device.rs | 92 | ||||
-rw-r--r-- | src/routes/mod.rs | 3 | ||||
-rw-r--r-- | src/routes/start.rs | 52 |
13 files changed, 244 insertions, 56 deletions
@@ -1,2 +1,2 @@ | |||
1 | DATABASE_URL="sqlite:devices.sqlite" | 1 | DATABASE_URL="postgres://postgres:postgres@localhost:5432/webol" |
2 | SQLX_OFFLINE_DIR="./.sqlx" \ No newline at end of file | 2 | SQLX_OFFLINE_DIR="./.sqlx" \ No newline at end of file |
diff --git a/.sqlx/query-3ed66b56b7e78a6b6bad9d49c49607520a8d09f902b996467dddf58737a3757f.json b/.sqlx/query-3ed66b56b7e78a6b6bad9d49c49607520a8d09f902b996467dddf58737a3757f.json new file mode 100644 index 0000000..feedac8 --- /dev/null +++ b/.sqlx/query-3ed66b56b7e78a6b6bad9d49c49607520a8d09f902b996467dddf58737a3757f.json | |||
@@ -0,0 +1,16 @@ | |||
1 | { | ||
2 | "db_name": "PostgreSQL", | ||
3 | "query": "\n INSERT INTO devices (id, mac, broadcast_addr)\n VALUES ($1, $2, $3);\n ", | ||
4 | "describe": { | ||
5 | "columns": [], | ||
6 | "parameters": { | ||
7 | "Left": [ | ||
8 | "Text", | ||
9 | "Text", | ||
10 | "Text" | ||
11 | ] | ||
12 | }, | ||
13 | "nullable": [] | ||
14 | }, | ||
15 | "hash": "3ed66b56b7e78a6b6bad9d49c49607520a8d09f902b996467dddf58737a3757f" | ||
16 | } | ||
diff --git a/.sqlx/query-6a81887a8b44b527ad04c8963d5186b764ec9125d597f9fba566e280bd09d352.json b/.sqlx/query-6a81887a8b44b527ad04c8963d5186b764ec9125d597f9fba566e280bd09d352.json new file mode 100644 index 0000000..89f6bbe --- /dev/null +++ b/.sqlx/query-6a81887a8b44b527ad04c8963d5186b764ec9125d597f9fba566e280bd09d352.json | |||
@@ -0,0 +1,36 @@ | |||
1 | { | ||
2 | "db_name": "PostgreSQL", | ||
3 | "query": "\n UPDATE devices\n SET mac = $1, broadcast_addr = $2 WHERE id = $3\n RETURNING id, mac, broadcast_addr;\n ", | ||
4 | "describe": { | ||
5 | "columns": [ | ||
6 | { | ||
7 | "ordinal": 0, | ||
8 | "name": "id", | ||
9 | "type_info": "Text" | ||
10 | }, | ||
11 | { | ||
12 | "ordinal": 1, | ||
13 | "name": "mac", | ||
14 | "type_info": "Text" | ||
15 | }, | ||
16 | { | ||
17 | "ordinal": 2, | ||
18 | "name": "broadcast_addr", | ||
19 | "type_info": "Text" | ||
20 | } | ||
21 | ], | ||
22 | "parameters": { | ||
23 | "Left": [ | ||
24 | "Text", | ||
25 | "Text", | ||
26 | "Text" | ||
27 | ] | ||
28 | }, | ||
29 | "nullable": [ | ||
30 | false, | ||
31 | false, | ||
32 | false | ||
33 | ] | ||
34 | }, | ||
35 | "hash": "6a81887a8b44b527ad04c8963d5186b764ec9125d597f9fba566e280bd09d352" | ||
36 | } | ||
diff --git a/.sqlx/query-035eea2a3ffbc6fcf5e1646f4e13e879b6e13325e38cd10d5ee160c5aded2caf.json b/.sqlx/query-bb9c6a42084b92c339a85f9b1c094959a49c6b7383f1a0b49df242e2720a9185.json index b1e99f6..efd2830 100644 --- a/.sqlx/query-035eea2a3ffbc6fcf5e1646f4e13e879b6e13325e38cd10d5ee160c5aded2caf.json +++ b/.sqlx/query-bb9c6a42084b92c339a85f9b1c094959a49c6b7383f1a0b49df242e2720a9185.json | |||
@@ -1,26 +1,28 @@ | |||
1 | { | 1 | { |
2 | "db_name": "SQLite", | 2 | "db_name": "PostgreSQL", |
3 | "query": "\n SELECT id, mac, broadcast_addr\n FROM devices\n WHERE id = ?1;\n ", | 3 | "query": "\n SELECT id, mac, broadcast_addr\n FROM devices\n WHERE id = $1;\n ", |
4 | "describe": { | 4 | "describe": { |
5 | "columns": [ | 5 | "columns": [ |
6 | { | 6 | { |
7 | "name": "id", | ||
8 | "ordinal": 0, | 7 | "ordinal": 0, |
8 | "name": "id", | ||
9 | "type_info": "Text" | 9 | "type_info": "Text" |
10 | }, | 10 | }, |
11 | { | 11 | { |
12 | "name": "mac", | ||
13 | "ordinal": 1, | 12 | "ordinal": 1, |
13 | "name": "mac", | ||
14 | "type_info": "Text" | 14 | "type_info": "Text" |
15 | }, | 15 | }, |
16 | { | 16 | { |
17 | "name": "broadcast_addr", | ||
18 | "ordinal": 2, | 17 | "ordinal": 2, |
18 | "name": "broadcast_addr", | ||
19 | "type_info": "Text" | 19 | "type_info": "Text" |
20 | } | 20 | } |
21 | ], | 21 | ], |
22 | "parameters": { | 22 | "parameters": { |
23 | "Right": 1 | 23 | "Left": [ |
24 | "Text" | ||
25 | ] | ||
24 | }, | 26 | }, |
25 | "nullable": [ | 27 | "nullable": [ |
26 | false, | 28 | false, |
@@ -28,5 +30,5 @@ | |||
28 | false | 30 | false |
29 | ] | 31 | ] |
30 | }, | 32 | }, |
31 | "hash": "035eea2a3ffbc6fcf5e1646f4e13e879b6e13325e38cd10d5ee160c5aded2caf" | 33 | "hash": "bb9c6a42084b92c339a85f9b1c094959a49c6b7383f1a0b49df242e2720a9185" |
32 | } | 34 | } |
@@ -1547,6 +1547,7 @@ dependencies = [ | |||
1547 | "sha2", | 1547 | "sha2", |
1548 | "sqlx-core", | 1548 | "sqlx-core", |
1549 | "sqlx-mysql", | 1549 | "sqlx-mysql", |
1550 | "sqlx-postgres", | ||
1550 | "sqlx-sqlite", | 1551 | "sqlx-sqlite", |
1551 | "syn 1.0.109", | 1552 | "syn 1.0.109", |
1552 | "tempfile", | 1553 | "tempfile", |
@@ -15,4 +15,4 @@ serde = { version = "1.0.188", features = ["derive"] } | |||
15 | serde_json = "1.0.107" | 15 | serde_json = "1.0.107" |
16 | config = "0.13.3" | 16 | config = "0.13.3" |
17 | once_cell = "1.18.0" | 17 | once_cell = "1.18.0" |
18 | sqlx = { version = "0.7.1", features = ["sqlite", "runtime-tokio"]} | 18 | sqlx = { version = "0.7.1", features = ["postgres", "runtime-tokio"]} |
diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..1980356 --- /dev/null +++ b/docker-compose.yml | |||
@@ -0,0 +1,11 @@ | |||
1 | version: '3.1' | ||
2 | |||
3 | services: | ||
4 | db: | ||
5 | image: postgres | ||
6 | restart: no | ||
7 | environment: | ||
8 | POSTGRES_PASSWORD: postgres | ||
9 | |||
10 | ports: | ||
11 | - "5432:5432" | ||
@@ -1,3 +1,6 @@ | |||
1 | use serde::Serialize; | ||
2 | |||
3 | #[derive(Serialize)] | ||
1 | pub struct Device { | 4 | pub struct Device { |
2 | pub id: String, | 5 | pub id: String, |
3 | pub mac: String, | 6 | pub mac: String, |
diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..afed111 --- /dev/null +++ b/src/error.rs | |||
@@ -0,0 +1,31 @@ | |||
1 | use std::error::Error; | ||
2 | use axum::http::StatusCode; | ||
3 | use axum::Json; | ||
4 | use axum::response::{IntoResponse, Response}; | ||
5 | use serde_json::json; | ||
6 | use tracing::error; | ||
7 | use crate::auth::AuthError; | ||
8 | |||
9 | pub enum WebolError { | ||
10 | Auth(AuthError), | ||
11 | Generic, | ||
12 | Server(Box<dyn Error>), | ||
13 | } | ||
14 | |||
15 | impl IntoResponse for WebolError { | ||
16 | fn into_response(self) -> Response { | ||
17 | let (status, error_message) = match self { | ||
18 | WebolError::Auth(err) => err.get(), | ||
19 | WebolError::Generic => (StatusCode::INTERNAL_SERVER_ERROR, ""), | ||
20 | WebolError::Server(err) => { | ||
21 | error!("server error: {}", err.to_string()); | ||
22 | (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") | ||
23 | }, | ||
24 | |||
25 | }; | ||
26 | let body = Json(json!({ | ||
27 | "error": error_message, | ||
28 | })); | ||
29 | (status, body).into_response() | ||
30 | } | ||
31 | } | ||
diff --git a/src/main.rs b/src/main.rs index 761e925..bb37dc2 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -1,9 +1,13 @@ | |||
1 | use std::env; | ||
1 | use std::sync::Arc; | 2 | use std::sync::Arc; |
2 | use axum::{Router, routing::post}; | 3 | use axum::{Router, routing::post}; |
3 | use sqlx::SqlitePool; | 4 | use axum::routing::{get, put}; |
5 | use sqlx::PgPool; | ||
6 | use sqlx::postgres::PgPoolOptions; | ||
4 | use time::util::local_offset; | 7 | use time::util::local_offset; |
5 | use tracing::{debug, info, level_filters::LevelFilter}; | 8 | use tracing::{debug, info, level_filters::LevelFilter}; |
6 | use tracing_subscriber::{EnvFilter, fmt::{self, time::LocalTime}, prelude::*}; | 9 | use tracing_subscriber::{EnvFilter, fmt::{self, time::LocalTime}, prelude::*}; |
10 | use crate::routes::device::{get_device, post_device, put_device}; | ||
7 | use crate::routes::start::start; | 11 | use crate::routes::start::start; |
8 | 12 | ||
9 | mod auth; | 13 | mod auth; |
@@ -11,6 +15,7 @@ mod config; | |||
11 | mod routes; | 15 | mod routes; |
12 | mod wol; | 16 | mod wol; |
13 | mod db; | 17 | mod db; |
18 | mod error; | ||
14 | 19 | ||
15 | #[tokio::main] | 20 | #[tokio::main] |
16 | async fn main() { | 21 | async fn main() { |
@@ -30,20 +35,20 @@ async fn main() { | |||
30 | ) | 35 | ) |
31 | .init(); | 36 | .init(); |
32 | 37 | ||
33 | debug!("connecting to db"); | ||
34 | let db = SqlitePool::connect("sqlite:devices.sqlite").await.unwrap(); | ||
35 | sqlx::migrate!().run(&db).await.unwrap(); | ||
36 | info!("connected to db"); | ||
37 | |||
38 | let version = env!("CARGO_PKG_VERSION"); | 38 | let version = env!("CARGO_PKG_VERSION"); |
39 | 39 | ||
40 | info!("starting webol v{}", version); | 40 | info!("starting webol v{}", version); |
41 | 41 | ||
42 | let db = init_db_pool().await; | ||
43 | |||
42 | let shared_state = Arc::new(AppState { db }); | 44 | let shared_state = Arc::new(AppState { db }); |
43 | 45 | ||
44 | // build our application with a single route | 46 | // build our application with a single route |
45 | let app = Router::new() | 47 | let app = Router::new() |
46 | .route("/start", post(start)) | 48 | .route("/start", post(start)) |
49 | .route("/device", get(get_device)) | ||
50 | .route("/device", put(put_device)) | ||
51 | .route("/device", post(post_device)) | ||
47 | .with_state(shared_state); | 52 | .with_state(shared_state); |
48 | 53 | ||
49 | // run it with hyper on localhost:3000 | 54 | // run it with hyper on localhost:3000 |
@@ -54,5 +59,21 @@ async fn main() { | |||
54 | } | 59 | } |
55 | 60 | ||
56 | pub struct AppState { | 61 | pub struct AppState { |
57 | db: SqlitePool | 62 | db: PgPool |
63 | } | ||
64 | |||
65 | async fn init_db_pool() -> PgPool { | ||
66 | let db_url = env::var("DATABASE_URL").unwrap(); | ||
67 | |||
68 | debug!("attempting to connect dbPool to '{}'", db_url); | ||
69 | |||
70 | let pool = PgPoolOptions::new() | ||
71 | .max_connections(5) | ||
72 | .connect(&db_url) | ||
73 | .await | ||
74 | .unwrap(); | ||
75 | |||
76 | info!("dbPool successfully connected to '{}'", db_url); | ||
77 | |||
78 | pool | ||
58 | } \ No newline at end of file | 79 | } \ No newline at end of file |
diff --git a/src/routes/device.rs b/src/routes/device.rs new file mode 100644 index 0000000..d5d7144 --- /dev/null +++ b/src/routes/device.rs | |||
@@ -0,0 +1,92 @@ | |||
1 | use std::sync::Arc; | ||
2 | use axum::extract::State; | ||
3 | use axum::headers::HeaderMap; | ||
4 | use axum::Json; | ||
5 | use serde::{Deserialize, Serialize}; | ||
6 | use serde_json::{json, Value}; | ||
7 | use crate::auth::auth; | ||
8 | use crate::db::Device; | ||
9 | use crate::error::WebolError; | ||
10 | |||
11 | pub async fn get_device(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<GetDevicePayload>) -> Result<Json<Value>, WebolError> { | ||
12 | let secret = headers.get("authorization"); | ||
13 | if auth(secret).map_err(WebolError::Auth)? { | ||
14 | let device = sqlx::query_as!( | ||
15 | Device, | ||
16 | r#" | ||
17 | SELECT id, mac, broadcast_addr | ||
18 | FROM devices | ||
19 | WHERE id = $1; | ||
20 | "#, | ||
21 | payload.id | ||
22 | ).fetch_one(&state.db).await.map_err(|err| WebolError::Server(Box::new(err)))?; | ||
23 | |||
24 | Ok(Json(json!(device))) | ||
25 | } else { | ||
26 | Err(WebolError::Generic) | ||
27 | } | ||
28 | } | ||
29 | |||
30 | #[derive(Deserialize)] | ||
31 | pub struct GetDevicePayload { | ||
32 | id: String, | ||
33 | } | ||
34 | |||
35 | pub async fn put_device(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<PutDevicePayload>) -> Result<Json<Value>, WebolError> { | ||
36 | let secret = headers.get("authorization"); | ||
37 | if auth(secret).map_err(WebolError::Auth)? { | ||
38 | sqlx::query!( | ||
39 | r#" | ||
40 | INSERT INTO devices (id, mac, broadcast_addr) | ||
41 | VALUES ($1, $2, $3); | ||
42 | "#, | ||
43 | payload.id, | ||
44 | payload.mac, | ||
45 | payload.broadcast_addr | ||
46 | ).execute(&state.db).await.map_err(|err| WebolError::Server(Box::new(err)))?; | ||
47 | |||
48 | Ok(Json(json!(PutDeviceResponse { success: true }))) | ||
49 | } else { | ||
50 | Err(WebolError::Generic) | ||
51 | } | ||
52 | } | ||
53 | |||
54 | #[derive(Deserialize)] | ||
55 | pub struct PutDevicePayload { | ||
56 | id: String, | ||
57 | mac: String, | ||
58 | broadcast_addr: String, | ||
59 | } | ||
60 | |||
61 | #[derive(Serialize)] | ||
62 | pub struct PutDeviceResponse { | ||
63 | success: bool | ||
64 | } | ||
65 | |||
66 | pub async fn post_device(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<PostDevicePayload>) -> Result<Json<Value>, WebolError> { | ||
67 | let secret = headers.get("authorization"); | ||
68 | if auth(secret).map_err(WebolError::Auth)? { | ||
69 | let device = sqlx::query_as!( | ||
70 | Device, | ||
71 | r#" | ||
72 | UPDATE devices | ||
73 | SET mac = $1, broadcast_addr = $2 WHERE id = $3 | ||
74 | RETURNING id, mac, broadcast_addr; | ||
75 | "#, | ||
76 | payload.mac, | ||
77 | payload.broadcast_addr, | ||
78 | payload.id | ||
79 | ).fetch_one(&state.db).await.map_err(|err| WebolError::Server(Box::new(err)))?; | ||
80 | |||
81 | Ok(Json(json!(device))) | ||
82 | } else { | ||
83 | Err(WebolError::Generic) | ||
84 | } | ||
85 | } | ||
86 | |||
87 | #[derive(Deserialize)] | ||
88 | pub struct PostDevicePayload { | ||
89 | id: String, | ||
90 | mac: String, | ||
91 | broadcast_addr: String, | ||
92 | } \ No newline at end of file | ||
diff --git a/src/routes/mod.rs b/src/routes/mod.rs index 78d4375..12fbfab 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs | |||
@@ -1 +1,2 @@ | |||
1 | pub mod start; \ No newline at end of file | 1 | pub mod start; |
2 | pub mod device; \ No newline at end of file | ||
diff --git a/src/routes/start.rs b/src/routes/start.rs index 2d505fc..d16ea4e 100644 --- a/src/routes/start.rs +++ b/src/routes/start.rs | |||
@@ -1,45 +1,43 @@ | |||
1 | use axum::headers::HeaderMap; | 1 | use axum::headers::HeaderMap; |
2 | use axum::http::StatusCode; | ||
3 | use axum::Json; | 2 | use axum::Json; |
4 | use axum::response::{IntoResponse, Response}; | ||
5 | use serde::{Deserialize, Serialize}; | 3 | use serde::{Deserialize, Serialize}; |
6 | use std::error::Error; | ||
7 | use std::sync::Arc; | 4 | use std::sync::Arc; |
8 | use axum::extract::State; | 5 | use axum::extract::State; |
9 | use serde_json::{json, Value}; | 6 | use serde_json::{json, Value}; |
10 | use tracing::{error, info}; | 7 | use tracing::info; |
11 | use crate::auth::{auth, AuthError}; | 8 | use crate::auth::auth; |
12 | use crate::config::SETTINGS; | 9 | use crate::config::SETTINGS; |
13 | use crate::wol::{create_buffer, send_packet}; | 10 | use crate::wol::{create_buffer, send_packet}; |
14 | use crate::db::Device; | 11 | use crate::db::Device; |
12 | use crate::error::WebolError; | ||
15 | 13 | ||
16 | pub async fn start(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<StartPayload>) -> Result<Json<Value>, StartError> { | 14 | pub async fn start(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<StartPayload>) -> Result<Json<Value>, WebolError> { |
17 | let secret = headers.get("authorization"); | 15 | let secret = headers.get("authorization"); |
18 | if auth(secret).map_err(StartError::Auth)? { | 16 | if auth(secret).map_err(WebolError::Auth)? { |
19 | let device = sqlx::query_as!( | 17 | let device = sqlx::query_as!( |
20 | Device, | 18 | Device, |
21 | r#" | 19 | r#" |
22 | SELECT id, mac, broadcast_addr | 20 | SELECT id, mac, broadcast_addr |
23 | FROM devices | 21 | FROM devices |
24 | WHERE id = ?1; | 22 | WHERE id = $1; |
25 | "#, | 23 | "#, |
26 | payload.id | 24 | payload.id |
27 | ).fetch_one(&state.db).await.map_err(|err| StartError::Server(Box::new(err)))?; | 25 | ).fetch_one(&state.db).await.map_err(|err| WebolError::Server(Box::new(err)))?; |
28 | 26 | ||
29 | info!("starting {}", device.id); | 27 | info!("starting {}", device.id); |
30 | 28 | ||
31 | let bind_addr = SETTINGS | 29 | let bind_addr = SETTINGS |
32 | .get_string("bindaddr") | 30 | .get_string("bindaddr") |
33 | .map_err(|err| StartError::Server(Box::new(err)))?; | 31 | .map_err(|err| WebolError::Server(Box::new(err)))?; |
34 | 32 | ||
35 | let _ = send_packet( | 33 | let _ = send_packet( |
36 | &bind_addr.parse().map_err(|err| StartError::Server(Box::new(err)))?, | 34 | &bind_addr.parse().map_err(|err| WebolError::Server(Box::new(err)))?, |
37 | &device.broadcast_addr.parse().map_err(|err| StartError::Server(Box::new(err)))?, | 35 | &device.broadcast_addr.parse().map_err(|err| WebolError::Server(Box::new(err)))?, |
38 | create_buffer(&device.mac).map_err(|err| StartError::Server(Box::new(err)))? | 36 | create_buffer(&device.mac).map_err(|err| WebolError::Server(Box::new(err)))? |
39 | ).map_err(|err| StartError::Server(Box::new(err))); | 37 | ).map_err(|err| WebolError::Server(Box::new(err))); |
40 | Ok(Json(json!(StartResponse { id: device.id, boot: true }))) | 38 | Ok(Json(json!(StartResponse { id: device.id, boot: true }))) |
41 | } else { | 39 | } else { |
42 | Err(StartError::Generic) | 40 | Err(WebolError::Generic) |
43 | } | 41 | } |
44 | } | 42 | } |
45 | 43 | ||
@@ -53,28 +51,4 @@ pub struct StartPayload { | |||
53 | struct StartResponse { | 51 | struct StartResponse { |
54 | id: String, | 52 | id: String, |
55 | boot: bool, | 53 | boot: bool, |
56 | } | ||
57 | |||
58 | pub enum StartError { | ||
59 | Auth(AuthError), | ||
60 | Generic, | ||
61 | Server(Box<dyn Error>), | ||
62 | } | ||
63 | |||
64 | impl IntoResponse for StartError { | ||
65 | fn into_response(self) -> Response { | ||
66 | let (status, error_message) = match self { | ||
67 | StartError::Auth(err) => err.get(), | ||
68 | StartError::Generic => (StatusCode::INTERNAL_SERVER_ERROR, ""), | ||
69 | StartError::Server(err) => { | ||
70 | error!("server error: {}", err.to_string()); | ||
71 | (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") | ||
72 | }, | ||
73 | |||
74 | }; | ||
75 | let body = Json(json!({ | ||
76 | "error": error_message, | ||
77 | })); | ||
78 | (status, body).into_response() | ||
79 | } | ||
80 | } \ No newline at end of file | 54 | } \ No newline at end of file |