mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 15:31:13 -05:00
Fix remaining compliance violations
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { serve } from "https://deno.land/std@0.168.0/http/server.ts";
|
||||
import { startRequest, endRequest } from "../_shared/logger.ts";
|
||||
import { edgeLogger, startRequest, endRequest } from "../_shared/logger.ts";
|
||||
|
||||
const corsHeaders = {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
@@ -36,14 +36,8 @@ function cleanupExpiredEntries() {
|
||||
}
|
||||
}
|
||||
|
||||
// Log cleanup activity for monitoring
|
||||
if (deletedCount > 0) {
|
||||
console.log(`[Cleanup] Removed ${deletedCount} expired entries. Map size: ${mapSizeBefore} -> ${rateLimitMap.size}`);
|
||||
}
|
||||
|
||||
// Reset failure count on successful cleanup
|
||||
// Cleanup runs silently unless there are issues
|
||||
if (cleanupFailureCount > 0) {
|
||||
console.log(`[Cleanup] Successful cleanup after ${cleanupFailureCount} previous failures. Resetting failure count.`);
|
||||
cleanupFailureCount = 0;
|
||||
}
|
||||
|
||||
@@ -52,20 +46,20 @@ function cleanupExpiredEntries() {
|
||||
cleanupFailureCount++;
|
||||
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
const errorStack = error instanceof Error ? error.stack : 'No stack trace available';
|
||||
|
||||
console.error('[Cleanup Error]', {
|
||||
edgeLogger.error('Cleanup error', {
|
||||
attempt: cleanupFailureCount,
|
||||
maxAttempts: MAX_CLEANUP_FAILURES,
|
||||
error: errorMessage,
|
||||
stack: errorStack,
|
||||
mapSize: rateLimitMap.size
|
||||
});
|
||||
|
||||
// FALLBACK MECHANISM: If cleanup fails repeatedly, force clear to prevent memory leak
|
||||
if (cleanupFailureCount >= MAX_CLEANUP_FAILURES) {
|
||||
console.error(`[Cleanup CRITICAL] Cleanup has failed ${cleanupFailureCount} times consecutively!`);
|
||||
console.error(`[Cleanup CRITICAL] Forcing emergency cleanup to prevent memory leak...`);
|
||||
edgeLogger.error('Cleanup critical - forcing emergency cleanup', {
|
||||
consecutiveFailures: cleanupFailureCount,
|
||||
mapSize: rateLimitMap.size
|
||||
});
|
||||
|
||||
try {
|
||||
// Emergency: Clear oldest 50% of entries to prevent unbounded growth
|
||||
@@ -79,20 +73,20 @@ function cleanupExpiredEntries() {
|
||||
clearedCount++;
|
||||
}
|
||||
|
||||
console.warn(`[Cleanup CRITICAL] Emergency cleanup completed. Cleared ${clearedCount} entries. Map size: ${rateLimitMap.size}`);
|
||||
edgeLogger.warn('Emergency cleanup completed', { clearedCount, newMapSize: rateLimitMap.size });
|
||||
|
||||
// Reset failure count after emergency cleanup
|
||||
cleanupFailureCount = 0;
|
||||
|
||||
} catch (emergencyError) {
|
||||
// Last resort: If even emergency cleanup fails, clear everything
|
||||
console.error(`[Cleanup CRITICAL] Emergency cleanup failed! Clearing entire rate limit map.`);
|
||||
console.error(`[Cleanup CRITICAL] Emergency error: ${emergencyError}`);
|
||||
|
||||
const originalSize = rateLimitMap.size;
|
||||
rateLimitMap.clear();
|
||||
|
||||
console.warn(`[Cleanup CRITICAL] Cleared entire rate limit map (${originalSize} entries) to prevent memory leak.`);
|
||||
edgeLogger.error('Emergency cleanup failed - cleared entire map', {
|
||||
originalSize,
|
||||
error: emergencyError instanceof Error ? emergencyError.message : String(emergencyError)
|
||||
});
|
||||
cleanupFailureCount = 0;
|
||||
}
|
||||
}
|
||||
@@ -102,7 +96,6 @@ function cleanupExpiredEntries() {
|
||||
// Reset cleanup failure count periodically to avoid permanent emergency state
|
||||
setInterval(() => {
|
||||
if (cleanupFailureCount > 0) {
|
||||
console.warn(`[Cleanup] Resetting failure count (was ${cleanupFailureCount}) after timeout period.`);
|
||||
cleanupFailureCount = 0;
|
||||
}
|
||||
}, CLEANUP_FAILURE_RESET_INTERVAL);
|
||||
@@ -140,11 +133,17 @@ function checkRateLimit(ip: string): { allowed: boolean; retryAfter?: number } {
|
||||
deletedCount++;
|
||||
}
|
||||
|
||||
console.warn(`[Rate Limit] Map reached ${MAX_MAP_SIZE} entries. Cleared ${deletedCount} oldest entries. New size: ${rateLimitMap.size}`);
|
||||
edgeLogger.warn('Rate limit map at capacity - evicted entries', {
|
||||
maxSize: MAX_MAP_SIZE,
|
||||
deletedCount,
|
||||
newSize: rateLimitMap.size
|
||||
});
|
||||
} catch (evictionError) {
|
||||
// CRITICAL: LRU eviction failed - log error and attempt emergency clear
|
||||
console.error(`[Rate Limit CRITICAL] LRU eviction failed! Error: ${evictionError}`);
|
||||
console.error(`[Rate Limit CRITICAL] Map size: ${rateLimitMap.size}`);
|
||||
edgeLogger.error('LRU eviction failed', {
|
||||
error: evictionError instanceof Error ? evictionError.message : String(evictionError),
|
||||
mapSize: rateLimitMap.size
|
||||
});
|
||||
|
||||
try {
|
||||
// Emergency: Clear first 30% of entries without sorting
|
||||
@@ -158,9 +157,14 @@ function checkRateLimit(ip: string): { allowed: boolean; retryAfter?: number } {
|
||||
|
||||
keysToDelete.forEach(key => rateLimitMap.delete(key));
|
||||
|
||||
console.warn(`[Rate Limit CRITICAL] Emergency eviction cleared ${keysToDelete.length} entries. New size: ${rateLimitMap.size}`);
|
||||
edgeLogger.warn('Emergency eviction completed', {
|
||||
clearedCount: keysToDelete.length,
|
||||
newSize: rateLimitMap.size
|
||||
});
|
||||
} catch (emergencyError) {
|
||||
console.error(`[Rate Limit CRITICAL] Emergency eviction also failed! Clearing entire map. Error: ${emergencyError}`);
|
||||
edgeLogger.error('Emergency eviction failed - clearing entire map', {
|
||||
error: emergencyError instanceof Error ? emergencyError.message : String(emergencyError)
|
||||
});
|
||||
rateLimitMap.clear();
|
||||
}
|
||||
}
|
||||
@@ -211,7 +215,7 @@ serve(async (req) => {
|
||||
}
|
||||
|
||||
// PII Note: Do not log full IP addresses in production
|
||||
console.log('[Location] Detecting location for request');
|
||||
edgeLogger.info('Detecting location for request', { requestId: tracking.requestId });
|
||||
|
||||
// Use configurable geolocation service with proper error handling
|
||||
// Defaults to ip-api.com if not configured
|
||||
@@ -222,7 +226,10 @@ serve(async (req) => {
|
||||
try {
|
||||
geoResponse = await fetch(`${geoApiUrl}/${clientIP}?fields=${geoApiFields}`);
|
||||
} catch (fetchError) {
|
||||
console.error('Network error fetching location data:', fetchError);
|
||||
edgeLogger.error('Network error fetching location data', {
|
||||
error: fetchError instanceof Error ? fetchError.message : String(fetchError),
|
||||
requestId: tracking.requestId
|
||||
});
|
||||
throw new Error('Network error: Unable to reach geolocation service');
|
||||
}
|
||||
|
||||
@@ -234,7 +241,10 @@ serve(async (req) => {
|
||||
try {
|
||||
geoData = await geoResponse.json();
|
||||
} catch (parseError) {
|
||||
console.error('Failed to parse geolocation response:', parseError);
|
||||
edgeLogger.error('Failed to parse geolocation response', {
|
||||
error: parseError instanceof Error ? parseError.message : String(parseError),
|
||||
requestId: tracking.requestId
|
||||
});
|
||||
throw new Error('Invalid response format from geolocation service');
|
||||
}
|
||||
|
||||
@@ -252,7 +262,7 @@ serve(async (req) => {
|
||||
measurementSystem
|
||||
};
|
||||
|
||||
console.log('[Location] Location detected:', {
|
||||
edgeLogger.info('Location detected', {
|
||||
country: result.country,
|
||||
countryCode: result.countryCode,
|
||||
measurementSystem: result.measurementSystem,
|
||||
@@ -275,12 +285,9 @@ serve(async (req) => {
|
||||
} catch (error: unknown) {
|
||||
// Enhanced error logging for better visibility and debugging
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
const errorStack = error instanceof Error ? error.stack : 'No stack trace available';
|
||||
|
||||
console.error('[Location Detection Error]', {
|
||||
edgeLogger.error('Location detection error', {
|
||||
error: errorMessage,
|
||||
stack: errorStack,
|
||||
hasIP: true, // IP removed for PII protection
|
||||
requestId: tracking.requestId
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user