mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-21 08:11:12 -05:00
feat: Implement comprehensive request tracking and state management
This commit is contained in:
114
src/lib/edgeFunctionTracking.ts
Normal file
114
src/lib/edgeFunctionTracking.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* Edge Function Request Tracking Wrapper
|
||||
*
|
||||
* Wraps Supabase function invocations with request tracking for debugging and monitoring.
|
||||
* Provides correlation IDs for tracing requests across the system.
|
||||
*/
|
||||
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { trackRequest } from './requestTracking';
|
||||
import { getErrorMessage } from './errorHandler';
|
||||
|
||||
/**
|
||||
* Invoke a Supabase edge function with request tracking
|
||||
*
|
||||
* @param functionName - Name of the edge function to invoke
|
||||
* @param payload - Request payload
|
||||
* @param userId - User ID for tracking (optional)
|
||||
* @param parentRequestId - Parent request ID for chaining (optional)
|
||||
* @param traceId - Trace ID for distributed tracing (optional)
|
||||
* @returns Response data with requestId
|
||||
*/
|
||||
export async function invokeWithTracking<T = any>(
|
||||
functionName: string,
|
||||
payload: Record<string, unknown> = {},
|
||||
userId?: string,
|
||||
parentRequestId?: string,
|
||||
traceId?: string
|
||||
): Promise<{ data: T | null; error: any; requestId: string; duration: number }> {
|
||||
try {
|
||||
const { result, requestId, duration } = await trackRequest(
|
||||
{
|
||||
endpoint: `/functions/${functionName}`,
|
||||
method: 'POST',
|
||||
userId,
|
||||
parentRequestId,
|
||||
traceId,
|
||||
},
|
||||
async (context) => {
|
||||
// Include client request ID in payload for correlation
|
||||
const { data, error } = await supabase.functions.invoke<T>(functionName, {
|
||||
body: { ...payload, clientRequestId: context.requestId },
|
||||
});
|
||||
|
||||
if (error) throw error;
|
||||
return data;
|
||||
}
|
||||
);
|
||||
|
||||
return { data: result, error: null, requestId, duration };
|
||||
} catch (error: unknown) {
|
||||
const errorMessage = getErrorMessage(error);
|
||||
// On error, we don't have tracking info, so create basic response
|
||||
return {
|
||||
data: null,
|
||||
error: { message: errorMessage },
|
||||
requestId: 'unknown',
|
||||
duration: 0,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke multiple edge functions in parallel with batch tracking
|
||||
*
|
||||
* Uses a shared trace ID to correlate all operations.
|
||||
*
|
||||
* @param operations - Array of function invocation configurations
|
||||
* @param userId - User ID for tracking
|
||||
* @returns Array of results with their request IDs
|
||||
*/
|
||||
export async function invokeBatchWithTracking<T = any>(
|
||||
operations: Array<{
|
||||
functionName: string;
|
||||
payload: Record<string, unknown>;
|
||||
}>,
|
||||
userId?: string
|
||||
): Promise<
|
||||
Array<{
|
||||
functionName: string;
|
||||
data: T | null;
|
||||
error: any;
|
||||
requestId: string;
|
||||
duration: number;
|
||||
}>
|
||||
> {
|
||||
const traceId = crypto.randomUUID();
|
||||
|
||||
const results = await Promise.allSettled(
|
||||
operations.map(async (op) => {
|
||||
const result = await invokeWithTracking<T>(
|
||||
op.functionName,
|
||||
op.payload,
|
||||
userId,
|
||||
undefined,
|
||||
traceId
|
||||
);
|
||||
return { functionName: op.functionName, ...result };
|
||||
})
|
||||
);
|
||||
|
||||
return results.map((result, index) => {
|
||||
if (result.status === 'fulfilled') {
|
||||
return result.value;
|
||||
} else {
|
||||
return {
|
||||
functionName: operations[index].functionName,
|
||||
data: null,
|
||||
error: { message: result.reason?.message || 'Unknown error' },
|
||||
requestId: 'unknown',
|
||||
duration: 0,
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user