Fix remaining compliance violations

This commit is contained in:
gpt-engineer-app[bot]
2025-11-03 18:47:59 +00:00
parent 6efb6dda66
commit 7663205512
9 changed files with 131 additions and 83 deletions

View File

@@ -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
});