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