Add robust dev fetch logging
Improve ApiDevTools to log fetch errors with stack traces during development, fix UUID generation fallback for environments lacking crypto.randomUUID, and ensure errors are surfaced in the browser console for easier debugging. Includes fallback generateUUID and preserved patching with proper catch blocks. X-Lovable-Edit-ID: edt-83e14dbc-6e2d-4ff9-9d17-d881d62d7da6
This commit is contained in:
@@ -46,6 +46,20 @@ function clearLogs() {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fallback UUID generator for environments where crypto.randomUUID is unavailable
|
||||||
|
function generateUUID(): string {
|
||||||
|
try {
|
||||||
|
return crypto.randomUUID();
|
||||||
|
} catch {
|
||||||
|
// Fallback implementation
|
||||||
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
||||||
|
const r = (Math.random() * 16) | 0;
|
||||||
|
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
||||||
|
return v.toString(16);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Intercept fetch (dev only)
|
// Intercept fetch (dev only)
|
||||||
const isDev = import.meta.env.DEV;
|
const isDev = import.meta.env.DEV;
|
||||||
const originalFetch = window.fetch;
|
const originalFetch = window.fetch;
|
||||||
@@ -55,23 +69,24 @@ const globalAny = window as unknown as { __gatehouseFetchPatched?: boolean };
|
|||||||
if (isDev && !globalAny.__gatehouseFetchPatched) {
|
if (isDev && !globalAny.__gatehouseFetchPatched) {
|
||||||
globalAny.__gatehouseFetchPatched = true;
|
globalAny.__gatehouseFetchPatched = true;
|
||||||
|
|
||||||
window.fetch = async function (input, init) {
|
try {
|
||||||
const url =
|
window.fetch = async function (input, init) {
|
||||||
typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
const url =
|
||||||
|
typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
||||||
|
|
||||||
// Log calls that look like our backend API (support both absolute + relative base URLs)
|
// Log calls that look like our backend API (support both absolute + relative base URLs)
|
||||||
const shouldLog =
|
const shouldLog =
|
||||||
url.includes("/api/") ||
|
url.includes("/api/") ||
|
||||||
url.includes("/api/v1") ||
|
url.includes("/api/v1") ||
|
||||||
url.includes("/auth/") ||
|
url.includes("/auth/") ||
|
||||||
url.includes("/users/") ||
|
url.includes("/users/") ||
|
||||||
url.includes("/org/");
|
url.includes("/org/");
|
||||||
|
|
||||||
if (!shouldLog) {
|
if (!shouldLog) {
|
||||||
return originalFetch.apply(this, [input, init]);
|
return originalFetch.apply(this, [input, init]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const id = crypto.randomUUID();
|
const id = generateUUID();
|
||||||
const method = init?.method || "GET";
|
const method = init?.method || "GET";
|
||||||
let requestBody: unknown;
|
let requestBody: unknown;
|
||||||
|
|
||||||
@@ -147,10 +162,15 @@ if (isDev && !globalAny.__gatehouseFetchPatched) {
|
|||||||
});
|
});
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
} catch (patchError) {
|
||||||
|
// Log any errors during fetch patching with full stack trace
|
||||||
|
console.error("[Gatehouse DevTools] Failed to patch fetch:", patchError);
|
||||||
|
if (patchError instanceof Error) {
|
||||||
|
console.error("[Gatehouse DevTools] Stack trace:", patchError.stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// isDev is already declared at module level for the fetch patch
|
|
||||||
export default function ApiDevTools() {
|
export default function ApiDevTools() {
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [logs, setLogs] = useState<ApiLog[]>([...apiLogs]);
|
const [logs, setLogs] = useState<ApiLog[]>([...apiLogs]);
|
||||||
|
|||||||
Reference in New Issue
Block a user