From 18f5b48e36d1750c5ae31368ae2bfcab3bfffde0 Mon Sep 17 00:00:00 2001 From: oche2920 Date: Tue, 23 Jun 2026 14:30:43 +0100 Subject: [PATCH] feat: add dev-only error logging utility - Add normalizeError helper to extract message + stack from any thrown value - Add logError gated behind __DEV__ (no-op in production builds) - Wire logError into fetchCatalog and fetchRegistryStatus Closes #25 --- src/api/resources.ts | 27 +++++++++++++++++++-------- src/utils/logger.ts | 20 ++++++++++++++++++++ 2 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 src/utils/logger.ts diff --git a/src/api/resources.ts b/src/api/resources.ts index 6ebfc70..1ce58f2 100644 --- a/src/api/resources.ts +++ b/src/api/resources.ts @@ -1,6 +1,7 @@ import Constants from "expo-constants"; import type { CatalogFilters, RegistryStatus, Resource } from "../types"; +import { logError } from "../utils/logger"; const API_BASE = (Constants.expoConfig?.extra?.apiUrl as string | undefined) ?? "http://localhost:4021"; @@ -22,19 +23,29 @@ function buildQuery(filters?: CatalogFilters): string { } export async function fetchCatalog(filters?: CatalogFilters): Promise { - const res = await fetch(`${API_BASE}/resources${buildQuery(filters)}`); - if (!res.ok) { - throw new Error("Failed to fetch catalog"); + try { + const res = await fetch(`${API_BASE}/resources${buildQuery(filters)}`); + if (!res.ok) { + throw new Error("Failed to fetch catalog"); + } + return res.json(); + } catch (err) { + logError("fetchCatalog", err); + throw err; } - return res.json(); } export async function fetchRegistryStatus(): Promise { - const res = await fetch(`${API_BASE}/registry/status`); - if (!res.ok) { - throw new Error("Failed to fetch registry status"); + try { + const res = await fetch(`${API_BASE}/registry/status`); + if (!res.ok) { + throw new Error("Failed to fetch registry status"); + } + return res.json(); + } catch (err) { + logError("fetchRegistryStatus", err); + throw err; } - return res.json(); } export function getApiBaseUrl(): string { diff --git a/src/utils/logger.ts b/src/utils/logger.ts new file mode 100644 index 0000000..fe90444 --- /dev/null +++ b/src/utils/logger.ts @@ -0,0 +1,20 @@ +const isDev = process.env.NODE_ENV === "development" || __DEV__; + +export interface NormalizedError { + message: string; + stack?: string; +} + +export function normalizeError(err: unknown): NormalizedError { + if (err instanceof Error) { + return { message: err.message, stack: err.stack }; + } + return { message: String(err) }; +} + +export function logError(context: string, err: unknown): void { + if (!isDev) return; + const { message, stack } = normalizeError(err); + console.error(`[MindVault] ${context}:`, message); + if (stack) console.error(stack); +}