diff --git a/src/lib/submissionItemsService.ts b/src/lib/submissionItemsService.ts index 131c6995..cae2d991 100644 --- a/src/lib/submissionItemsService.ts +++ b/src/lib/submissionItemsService.ts @@ -72,7 +72,13 @@ export async function fetchSubmissionItems(submissionId: string): Promise { @@ -84,14 +90,23 @@ export async function fetchSubmissionItems(submissionId: string): Promise { ); // Log notification in notification_logs with idempotency key - await supabase.from('notification_logs').insert({ + const { error: logError } = await supabase.from('notification_logs').insert({ user_id: '00000000-0000-0000-0000-000000000000', // Topic-based notification_type: 'moderation_submission', idempotency_key: idempotencyKey, @@ -225,13 +225,23 @@ serve(async (req) => { } }); + if (logError) { + // Non-blocking - notification was sent successfully, log failure shouldn't fail the request + edgeLogger.warn('Failed to log notification in notification_logs', { + action: 'notify_moderators', + requestId: tracking.requestId, + error: logError.message, + submissionId: submission_id + }); + } + const duration = endRequest(tracking); - edgeLogger.info('Successfully notified all moderators via topic', { + edgeLogger.info('Successfully notified all moderators via topic', { action: 'notify_moderators', requestId: tracking.requestId, traceId: tracking.traceId, duration, - transactionId: data?.transactionId + transactionId: data?.transactionId }); return new Response( diff --git a/supabase/functions/process-selective-approval/index.ts b/supabase/functions/process-selective-approval/index.ts index f362735f..2e1bec25 100644 --- a/supabase/functions/process-selective-approval/index.ts +++ b/supabase/functions/process-selective-approval/index.ts @@ -213,14 +213,19 @@ const handler = async (req: Request) => { console.error(`[${requestId}] Approval transaction failed:`, rpcError); // Update idempotency key to failed - await supabase - .from('submission_idempotency_keys') - .update({ - status: 'failed', - error_message: rpcError.message, - completed_at: new Date().toISOString() - }) - .eq('idempotency_key', idempotencyKey); + try { + await supabase + .from('submission_idempotency_keys') + .update({ + status: 'failed', + error_message: rpcError.message, + completed_at: new Date().toISOString() + }) + .eq('idempotency_key', idempotencyKey); + } catch (updateError) { + console.error(`[${requestId}] Failed to update idempotency key to failed:`, updateError); + // Non-blocking - continue with error response even if idempotency update fails + } return new Response( JSON.stringify({ @@ -229,12 +234,12 @@ const handler = async (req: Request) => { details: rpcError.details, retries: retryCount }), - { - status: 500, - headers: { + { + status: 500, + headers: { ...corsHeaders, - 'Content-Type': 'application/json' - } + 'Content-Type': 'application/json' + } } ); } @@ -242,14 +247,19 @@ const handler = async (req: Request) => { console.log(`[${requestId}] Transaction completed successfully:`, result); // STEP 8: Success - update idempotency key - await supabase - .from('submission_idempotency_keys') - .update({ - status: 'completed', - result_data: result, - completed_at: new Date().toISOString() - }) - .eq('idempotency_key', idempotencyKey); + try { + await supabase + .from('submission_idempotency_keys') + .update({ + status: 'completed', + result_data: result, + completed_at: new Date().toISOString() + }) + .eq('idempotency_key', idempotencyKey); + } catch (updateError) { + console.error(`[${requestId}] Failed to update idempotency key to completed:`, updateError); + // Non-blocking - transaction succeeded, so continue with success response + } return new Response( JSON.stringify(result), diff --git a/supabase/functions/upload-image/index.ts b/supabase/functions/upload-image/index.ts index c2a2c700..0f188cb3 100644 --- a/supabase/functions/upload-image/index.ts +++ b/supabase/functions/upload-image/index.ts @@ -107,24 +107,25 @@ serve(withRateLimit(async (req) => { const tracking = startRequest(); const requestOrigin = req.headers.get('origin'); const allowedOrigin = getAllowedOrigin(requestOrigin); - - // Check if this is a CORS request with a disallowed origin + + // Check if this is a CORS request with a disallowed origin if (requestOrigin && !allowedOrigin) { edgeLogger.warn('CORS request rejected', { action: 'cors_validation', origin: requestOrigin, requestId: tracking.requestId }); return new Response( - JSON.stringify({ + JSON.stringify({ error: 'Origin not allowed', message: 'The origin of this request is not allowed to access this resource' }), - { + { status: 403, headers: { 'Content-Type': 'application/json' } } ); } - + + // Define CORS headers at function scope so they're available in catch block const corsHeaders = getCorsHeaders(allowedOrigin); - + // Handle CORS preflight requests if (req.method === 'OPTIONS') { return new Response(null, { headers: corsHeaders })