mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 10:11:13 -05:00
Improve moderation edge flow and timeout handling
- Add early logging and health check to process-selective-approval edge function - Implement idempotency check with timeout to avoid edge timeouts - Expose health endpoint for connectivity diagnostics - Increase client moderation action timeout from 30s to 60s - Update moderation actions hook to accommodate longer timeouts
This commit is contained in:
@@ -16,11 +16,42 @@ import { ValidationError } from '../_shared/typeValidation.ts';
|
||||
const handler = async (req: Request, context: { supabase: any; user: any; span: any; requestId: string }) => {
|
||||
const { supabase, user, span: rootSpan, requestId } = context;
|
||||
|
||||
// Early logging - confirms request reached handler
|
||||
addSpanEvent(rootSpan, 'handler_entry', {
|
||||
requestId,
|
||||
userId: user.id,
|
||||
timestamp: Date.now()
|
||||
});
|
||||
|
||||
setSpanAttributes(rootSpan, {
|
||||
'user.id': user.id,
|
||||
'function.name': 'process-selective-approval'
|
||||
});
|
||||
|
||||
// Health check endpoint
|
||||
if (req.url.includes('/health')) {
|
||||
addSpanEvent(rootSpan, 'health_check_start');
|
||||
const { data, error } = await supabase
|
||||
.from('content_submissions')
|
||||
.select('count')
|
||||
.limit(1);
|
||||
|
||||
addSpanEvent(rootSpan, 'health_check_complete', {
|
||||
dbConnected: !error,
|
||||
error: error?.message
|
||||
});
|
||||
|
||||
return new Response(JSON.stringify({
|
||||
status: 'ok',
|
||||
dbConnected: !error,
|
||||
timestamp: Date.now(),
|
||||
error: error?.message
|
||||
}), {
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
status: error ? 500 : 200
|
||||
});
|
||||
}
|
||||
|
||||
// STEP 1: Parse and validate request
|
||||
addSpanEvent(rootSpan, 'validation_start');
|
||||
|
||||
@@ -57,14 +88,37 @@ const handler = async (req: Request, context: { supabase: any; user: any; span:
|
||||
});
|
||||
addSpanEvent(rootSpan, 'validation_complete');
|
||||
|
||||
// STEP 2: Idempotency check
|
||||
// STEP 2: Idempotency check with timeout
|
||||
addSpanEvent(rootSpan, 'idempotency_check_start');
|
||||
const { data: existingKey } = await supabase
|
||||
|
||||
const idempotencyCheckPromise = supabase
|
||||
.from('submission_idempotency_keys')
|
||||
.select('*')
|
||||
.eq('idempotency_key', idempotencyKey)
|
||||
.single();
|
||||
|
||||
// Add 5 second timeout for idempotency check
|
||||
const timeoutPromise = new Promise((_, reject) =>
|
||||
setTimeout(() => reject(new Error('Idempotency check timed out after 5s')), 5000)
|
||||
);
|
||||
|
||||
let existingKey;
|
||||
try {
|
||||
const result = await Promise.race([
|
||||
idempotencyCheckPromise,
|
||||
timeoutPromise
|
||||
]) as any;
|
||||
existingKey = result.data;
|
||||
} catch (timeoutError: any) {
|
||||
addSpanEvent(rootSpan, 'idempotency_check_timeout', { error: timeoutError.message });
|
||||
throw new Error(`Database query timeout: ${timeoutError.message}`);
|
||||
}
|
||||
|
||||
addSpanEvent(rootSpan, 'idempotency_check_complete', {
|
||||
foundKey: !!existingKey,
|
||||
status: existingKey?.status
|
||||
});
|
||||
|
||||
if (existingKey?.status === 'completed') {
|
||||
addSpanEvent(rootSpan, 'idempotency_cache_hit');
|
||||
setSpanAttributes(rootSpan, { 'cache.hit': true });
|
||||
|
||||
Reference in New Issue
Block a user