refactor: Clean up unused imports and improve error handling in middleware and DTOs

This commit is contained in:
MythEclipse
2025-10-23 22:44:32 +07:00
parent 6915a97d79
commit 3fcfb3709e
7 changed files with 47 additions and 18 deletions
+25 -2
View File
@@ -57,8 +57,31 @@ pub async fn auth_middleware(
} else {
match state.user_lookup_service.get_user_by_id_internal(&thing_id, &state).await {
Ok(user) => {
// Cache in mem for future requests
let _: Result<Option<UsersDetailQueryDto>, _> = mem_db.update(("users", &user_id)).content(user.clone()).await;
// Cache in mem for future requests with retry logic
let mut retry_count = 0;
const MAX_RETRIES: u8 = 3;
while retry_count < MAX_RETRIES {
match mem_db.update::<Option<UsersDetailQueryDto>>(("users", &user_id)).content(user.clone()).await {
Ok(_) => {
log::debug!("User {} cached successfully", user_id);
break;
}
Err(e) => {
retry_count += 1;
log::warn!(
"Failed to cache user {} (attempt {}/{}): {}",
user_id, retry_count, MAX_RETRIES, e
);
if retry_count < MAX_RETRIES {
tokio::time::sleep(tokio::time::Duration::from_millis(50 * retry_count as u64)).await;
} else {
log::error!("Failed to cache user {} after {} retries", user_id, MAX_RETRIES);
}
}
}
}
user
},
Err(_) => return Ok(common_response(StatusCode::UNAUTHORIZED, "User not found")),
@@ -130,19 +130,27 @@ async fn check_rate_limit(
record.increment();
}
// Update record di database
// Skip database update if it fails to avoid blocking the request
// Database update skipped for now to resolve compilation issues
// db.update(key).content(record.clone()).await.ok();
// Periksa apakah rate limit terlampaui sebelum update
let is_limited = record.is_rate_limited(max_requests);
// Periksa apakah rate limit terlampaui
Ok(record.is_rate_limited(max_requests))
// Update record di database
if let Err(e) = db.update::<Option<RateLimitSchema>>(key).content(record.clone()).await {
log::error!("Failed to update rate limit record for {}: {}", ip_address, e);
// Gagal update, tapi tetap enforce rate limit berdasarkan data yang ada
}
Ok(is_limited)
}
None => {
// Buat record baru jika belum ada
let new_record = RateLimitSchema::new(ip_address.to_string(), window_duration_secs);
// Database create skipped for now to resolve compilation issues
// db.create(key).content(new_record).await.ok();
// Simpan record baru ke database
if let Err(e) = db.create::<Option<RateLimitSchema>>(key).content(new_record).await {
log::error!("Failed to create rate limit record for {}: {}", ip_address, e);
// Jika gagal create, izinkan request (fail open untuk availability)
}
Ok(false) // Request pertama selalu diizinkan
}
}
@@ -119,8 +119,9 @@ fn add_security_headers(mut res: Response<axum::body::Body>, nonce: &str) -> Res
/// Generate a random nonce for CSP
fn generate_nonce() -> String {
let mut rng = rand::thread_rng();
use base64::{Engine as _, engine::general_purpose::STANDARD};
let mut rng = rand::rng();
let mut random_bytes = [0u8; 16];
rng.fill_bytes(&mut random_bytes);
base64::encode(random_bytes)
STANDARD.encode(random_bytes)
}
@@ -209,7 +209,7 @@ pub async fn validate_timeline_request_body(
async fn get_active_timeline_phases(
hackathon_id: String,
current_time: DateTime<Utc>,
app_state: &AppState,
_app_state: &AppState,
) -> Result<Vec<HackathonTimelinePhase>, String> {
// In a real implementation, this would call the hackathon service to get timeline phases
// For now, we'll return a mock implementation that demonstrates the pattern