feat(ui): add structured JSON logging to all server-side routes and lib

Introduces a logger.ts module emitting slog-compatible JSON lines to stderr.
Replaces silent catch blocks and console.error calls throughout minio.ts,
pocketbase.ts, hooks.server.ts, login, books, browse, and all API routes so
auth/registration failures, MinIO presign errors, and scraper proxy failures
are now visible in container logs.
This commit is contained in:
Admin
2026-03-03 14:34:48 +05:00
parent 5131ae0bc4
commit bf5774d8d0
13 changed files with 188 additions and 37 deletions

View File

@@ -8,6 +8,7 @@
import { env } from '$env/dynamic/private';
import { env as pubEnv } from '$env/dynamic/public';
import { log } from '$lib/server/logger';
const SCRAPER_URL = env.SCRAPER_API_URL ?? 'http://localhost:8080';
// Public MinIO URL — used to rewrite presigned URLs so the browser can reach MinIO directly.
@@ -40,9 +41,21 @@ function rewriteHost(presignedUrl: string): string {
* server-side (in a +page.server.ts load function) to fetch the markdown content.
*/
export async function presignChapter(slug: string, n: number): Promise<string> {
const res = await fetch(`${SCRAPER_URL}/api/presign/chapter/${slug}/${n}`);
if (!res.ok) throw new Error(`presign chapter ${slug}/${n}: ${res.status}`);
log.debug('minio', 'presigning chapter', { slug, n });
let res: Response;
try {
res = await fetch(`${SCRAPER_URL}/api/presign/chapter/${slug}/${n}`);
} catch (e) {
log.error('minio', 'presign chapter network error', { slug, n, err: String(e) });
throw new Error(`presign chapter ${slug}/${n}: network error`);
}
if (!res.ok) {
const body = await res.text().catch(() => '');
log.error('minio', 'presign chapter failed', { slug, n, status: res.status, body });
throw new Error(`presign chapter ${slug}/${n}: ${res.status}`);
}
const data = (await res.json()) as { url: string };
log.debug('minio', 'presign chapter ok', { slug, n });
return rewriteHost(data.url);
}
@@ -60,8 +73,20 @@ export async function presignAudio(
if (voice) params.set('voice', voice);
if (speed) params.set('speed', String(speed));
const qs = params.toString() ? `?${params.toString()}` : '';
const res = await fetch(`${SCRAPER_URL}/api/presign/audio/${slug}/${n}${qs}`);
if (!res.ok) throw new Error(`presign audio ${slug}/${n}: ${res.status}`);
log.debug('minio', 'presigning audio', { slug, n, voice, speed });
let res: Response;
try {
res = await fetch(`${SCRAPER_URL}/api/presign/audio/${slug}/${n}${qs}`);
} catch (e) {
log.error('minio', 'presign audio network error', { slug, n, err: String(e) });
throw new Error(`presign audio ${slug}/${n}: network error`);
}
if (!res.ok) {
const body = await res.text().catch(() => '');
log.error('minio', 'presign audio failed', { slug, n, status: res.status, body });
throw new Error(`presign audio ${slug}/${n}: ${res.status}`);
}
const data = (await res.json()) as { url: string };
log.debug('minio', 'presign audio ok', { slug, n });
return rewriteHost(data.url);
}