Improve error message when storing
This commit is contained in:
parent
821f0e6472
commit
b5a238c205
69
src/main.rs
69
src/main.rs
@ -93,24 +93,37 @@ struct RetrieveResponse {
|
|||||||
value: String,
|
value: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Store data on the filesystem
|
async fn get_file_path(key: &str) -> String {
|
||||||
async fn store_data(key: &str, value: &[u8], expires_at: SystemTime) -> Result<(), String> {
|
|
||||||
let dir_name = format!("{}/{}", STORAGE_DIR, &key[..2]);
|
let dir_name = format!("{}/{}", STORAGE_DIR, &key[..2]);
|
||||||
let file_path = format!("{}/{}", dir_name, &key[2..]);
|
let file_path = format!("{}/{}", dir_name, &key[2..]);
|
||||||
let metadata_path = format!("{}.meta", file_path);
|
|
||||||
|
|
||||||
create_dir_all(&dir_name).await.map_err(|e| e.to_string())?;
|
file_path
|
||||||
|
}
|
||||||
|
|
||||||
let mut file = File::create(&file_path).await.map_err(|e| e.to_string())?;
|
/// Store data on the filesystem
|
||||||
file.write_all(value).await.map_err(|e| e.to_string())?;
|
async fn store_data(key: &str, value: &[u8], expires_at: SystemTime) -> Result<(), tide::Error> {
|
||||||
|
let file_name = get_file_path(key).await;
|
||||||
|
let file_path = Path::new(&file_name);
|
||||||
|
|
||||||
|
// Check if key exists
|
||||||
|
if file_path.exists().await {
|
||||||
|
return Err(tide::Error::from_str(StatusCode::Conflict, "Key already exists"));
|
||||||
|
}
|
||||||
|
|
||||||
|
create_dir_all(file_path).await.map_err(|e| tide::Error::new(StatusCode::InternalServerError, e))?;
|
||||||
|
|
||||||
|
let metadata_path = format!("{}.meta", file_name);
|
||||||
|
|
||||||
|
let mut file = File::create(&file_path).await.map_err(|e| tide::Error::new(StatusCode::InternalServerError, e))?;
|
||||||
|
file.write_all(value).await.map_err(|e| tide::Error::new(StatusCode::InternalServerError, e))?;
|
||||||
|
|
||||||
let metadata = Metadata {
|
let metadata = Metadata {
|
||||||
expires_at: system_time_to_unix(expires_at)
|
expires_at: system_time_to_unix(expires_at)
|
||||||
};
|
};
|
||||||
|
|
||||||
let metadata_json = serde_json::to_string(&metadata).map_err(|e| e.to_string())?;
|
let metadata_json = serde_json::to_string(&metadata).map_err(|e| tide::Error::new(StatusCode::InternalServerError, e))?;
|
||||||
let mut meta_file = File::create(&metadata_path).await.map_err(|e| e.to_string())?;
|
let mut meta_file = File::create(&metadata_path).await.map_err(|e| tide::Error::new(StatusCode::InternalServerError, e))?;
|
||||||
meta_file.write_all(metadata_json.as_bytes()).await.map_err(|e| e.to_string())?;
|
meta_file.write_all(metadata_json.as_bytes()).await.map_err(|e| tide::Error::new(StatusCode::InternalServerError, e))?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -127,9 +140,14 @@ async fn retrieve_data(key: &str) -> Result<Vec<u8>, String> {
|
|||||||
/// Handler for the /store endpoint
|
/// Handler for the /store endpoint
|
||||||
async fn handle_store(mut req: Request<()>) -> tide::Result<Response> {
|
async fn handle_store(mut req: Request<()>) -> tide::Result<Response> {
|
||||||
// Parse the JSON body
|
// Parse the JSON body
|
||||||
let data: StoreRequest = req.body_json().await.map_err(|_| {
|
let data: StoreRequest = match req.body_json().await {
|
||||||
tide::Error::from_str(StatusCode::BadRequest, "Invalid JSON payload")
|
Ok(data) => data,
|
||||||
})?;
|
Err(e) => {
|
||||||
|
return Ok(Response::builder(StatusCode::BadRequest)
|
||||||
|
.body(format!("Invalid request: {}", e))
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Validate the key
|
// Validate the key
|
||||||
if data.key.len() != 64 || !data.key.chars().all(|c| c.is_ascii_hexdigit()) {
|
if data.key.len() != 64 || !data.key.chars().all(|c| c.is_ascii_hexdigit()) {
|
||||||
@ -139,26 +157,37 @@ async fn handle_store(mut req: Request<()>) -> tide::Result<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Decode the value from Base64
|
// Decode the value from Base64
|
||||||
let value_bytes = base64::decode(&data.value).map_err(|_| {
|
let value_bytes = match base64::decode(&data.value) {
|
||||||
tide::Error::from_str(StatusCode::BadRequest, "Invalid Base64 value")
|
Ok(value) => value,
|
||||||
})?;
|
Err(e) => {
|
||||||
|
return Ok(Response::builder(StatusCode::BadRequest)
|
||||||
|
.body(format!("Invalid request: {}", e))
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let now = SystemTime::now();
|
let now = SystemTime::now();
|
||||||
let live_for = if let Some(ttl) = data.ttl { Duration::from_secs(ttl) } else { Duration::from_secs(DEFAULT_TTL) };
|
let live_for = if let Some(ttl) = data.ttl { Duration::from_secs(ttl) } else { Duration::from_secs(DEFAULT_TTL) };
|
||||||
let expires_at = now.checked_add(live_for).ok_or(tide::Error::from_str(StatusCode::BadRequest, "Invalid ttl"))?;
|
let expires_at = now.checked_add(live_for).ok_or(tide::Error::from_str(StatusCode::BadRequest, "Invalid ttl"))?;
|
||||||
|
|
||||||
// Store the data
|
// Store the data
|
||||||
store_data(&data.key, &value_bytes, expires_at).await.map_err(|e| {
|
match store_data(&data.key, &value_bytes, expires_at).await {
|
||||||
tide::Error::from_str(StatusCode::InternalServerError, e)
|
Ok(()) => {
|
||||||
})?;
|
|
||||||
|
|
||||||
// Respond with success
|
|
||||||
Ok(Response::builder(StatusCode::Ok)
|
Ok(Response::builder(StatusCode::Ok)
|
||||||
.body(serde_json::to_value(&ApiResponse {
|
.body(serde_json::to_value(&ApiResponse {
|
||||||
message: "Data stored successfully.".to_string(),
|
message: "Data stored successfully.".to_string(),
|
||||||
})?)
|
})?)
|
||||||
.build())
|
.build())
|
||||||
}
|
}
|
||||||
|
Err(e) => {
|
||||||
|
Ok(Response::builder(e.status())
|
||||||
|
.body(serde_json::to_value(&ApiResponse {
|
||||||
|
message: e.to_string(),
|
||||||
|
})?)
|
||||||
|
.build())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn handle_retrieve(req: Request<()>) -> tide::Result<Response> {
|
async fn handle_retrieve(req: Request<()>) -> tide::Result<Response> {
|
||||||
let key: String = req.param("key")?.to_string();
|
let key: String = req.param("key")?.to_string();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user