Fix Supabase client proxy

This commit is contained in:
gpt-engineer-app[bot]
2025-11-04 17:37:30 +00:00
parent 87589ee08f
commit 2deab69ebe
2 changed files with 60 additions and 30 deletions

View File

@@ -101,6 +101,8 @@ export function useUnitPreferences() {
user_id: user.id,
unit_preferences: newPreferences as unknown as Json,
updated_at: new Date().toISOString()
}, {
onConflict: 'user_id'
});
if (error) {

View File

@@ -10,6 +10,62 @@ import { breadcrumb } from './errorBreadcrumbs';
type SupabaseClient = typeof baseClient;
/**
* Create a recursive proxy for query builders that tracks terminal method calls
*/
function createQueryProxy(queryBuilder: any, endpoint: string, operations: string[] = []): any {
return new Proxy(queryBuilder, {
get(target, prop: string | symbol) {
const value = target[prop];
if (typeof value !== 'function') {
return value;
}
// Terminal methods that execute queries and return promises
const terminalMethods = ['then', 'single', 'maybeSingle'];
if (terminalMethods.includes(String(prop))) {
// Wrap terminal method to log breadcrumb when promise resolves
return function(...args: any[]) {
const result = value.apply(target, args);
const fullOperation = operations.join('.');
// Intercept promise resolution to log breadcrumb
if (result && typeof result.then === 'function') {
return result.then(
(response: any) => {
// Log successful API call
breadcrumb.apiCall(
endpoint,
fullOperation || 'query',
response?.error ? 400 : 200
);
return response;
},
(error: any) => {
// Log failed API call
breadcrumb.apiCall(endpoint, fullOperation || 'query', 500);
throw error;
}
);
}
return result;
};
}
// Builder methods - pass through synchronously and continue proxying
return function(...args: any[]) {
const result = value.apply(target, args);
// Continue proxying the returned builder with accumulated operations
return createQueryProxy(result, endpoint, [...operations, String(prop)]);
};
}
});
}
/**
* Wrap Supabase client to automatically track API calls as breadcrumbs
*/
@@ -24,36 +80,8 @@ function wrapSupabaseClient(client: SupabaseClient): SupabaseClient {
const result = (value as any).apply(target, args);
const endpoint = prop === 'from' ? `/table/${args[0]}` : `/rpc/${args[0]}`;
// Return a proxy for chained query methods
return new Proxy(result, {
get(queryTarget: any, queryProp: string | symbol) {
const queryValue = queryTarget[queryProp];
// If it's a function, wrap it to track the call
if (typeof queryValue === 'function') {
return async (...queryArgs: any[]) => {
try {
const response = await queryValue.apply(queryTarget, queryArgs);
// Log breadcrumb after response
breadcrumb.apiCall(
endpoint,
String(queryProp).toUpperCase(),
response.error ? 400 : 200
);
return response;
} catch (error) {
// Log breadcrumb for exceptions
breadcrumb.apiCall(endpoint, String(queryProp).toUpperCase(), 500);
throw error;
}
};
}
return queryValue;
}
});
// Return a recursive proxy that tracks the query chain
return createQueryProxy(result, endpoint, []);
};
}