Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion apps/web/src/app/api/agents/actions/route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { NextResponse } from 'next/server';
import { formatApiError } from '@/lib/error-handling';
import { runActionAgent } from '@/lib/action-agent';
import { AVAILABLE_TOOL_NAMES } from '@/lib/action-agent';
import { hasGeminiKey } from '@/lib/gemini-client';
Expand Down Expand Up @@ -56,7 +57,7 @@ export async function POST(request: Request): Promise<NextResponse> {
});
} catch (error) {
console.error('Action agent error:', error);
const message = error instanceof Error ? error.message : String(error);
const message = formatApiError(error).message;

// Only the agent's own validation/config guards are client errors (400).
// Match exact phrases so an upstream provider error that merely mentions
Expand Down
3 changes: 2 additions & 1 deletion apps/web/src/app/api/extract-events/route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import OpenAI from 'openai';
import { formatApiError } from '@/lib/error-handling';
import { Type } from '@google/genai';
import { NextResponse } from 'next/server';
import { getGeminiClient, hasGeminiKey } from '@/lib/gemini-client';
Expand Down Expand Up @@ -255,7 +256,7 @@ Respond with ONLY valid JSON matching the required structure.`;
return NextResponse.json({ success: true, provider, data: parsed });
} catch (error) {
console.error('Event extraction error:', error);
const message = error instanceof Error ? error.message : String(error);
const message = formatApiError(error).message;

return NextResponse.json({
success: false,
Expand Down
5 changes: 3 additions & 2 deletions apps/web/src/app/api/jobs/[jobId]/route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { NextResponse } from 'next/server';
import { formatApiError } from '@/lib/error-handling';
import { backendHeaders } from '@/lib/pipeline-backend';

const rawBackendUrl = process.env.BACKEND_URL || '';
Expand Down Expand Up @@ -39,8 +40,8 @@ export async function GET(
});
} catch (error) {
return NextResponse.json(
{ error: error instanceof Error ? error.message : String(error) },
{ error: formatApiError(error).message },
{ status: 502 },
);
}
}
}
5 changes: 3 additions & 2 deletions apps/web/src/app/api/search/route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { NextRequest, NextResponse } from 'next/server';
import { formatApiError } from '@/lib/error-handling';
import { getSearchIndex, resolveSearchIndexName } from '@/lib/upstash-search';
import type { SearchDocument } from '@/lib/upstash-search';

Expand Down Expand Up @@ -44,7 +45,7 @@ export async function POST(req: NextRequest) {
} catch (error) {
console.error('Upstash search error:', error);
return NextResponse.json(
{ error: 'search_failed', detail: error instanceof Error ? error.message : String(error) },
{ error: 'search_failed', detail: formatApiError(error).message },
{ status: 502 },
);
}
Expand Down Expand Up @@ -108,7 +109,7 @@ export async function PUT(req: NextRequest) {
} catch (error) {
console.error('Upstash upsert error:', error);
return NextResponse.json(
{ error: 'upsert_failed', detail: error instanceof Error ? error.message : String(error) },
{ error: 'upsert_failed', detail: formatApiError(error).message },
{ status: 502 },
);
}
Expand Down
5 changes: 3 additions & 2 deletions apps/web/src/lib/gemini-client.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'server-only';
import { formatApiError } from '@/lib/error-handling';

/**
* Shared Gemini/Google AI client factory.
Expand Down Expand Up @@ -97,7 +98,7 @@ export function getGeminiRoutingLabel(): string {
* Map provider errors to stable codes for API responses and logs.
*/
export function classifyGeminiError(error: unknown): ClassifiedGeminiError {
const message = error instanceof Error ? error.message : String(error);
const message = formatApiError(error).message;

if (message.includes('BILLING_DISABLED')) {
return {
Expand Down Expand Up @@ -170,4 +171,4 @@ export function getGeminiClient(): GoogleGenAI {
_lastMode = mode;
}
return _gemini;
}
}
3 changes: 2 additions & 1 deletion apps/web/src/lib/gemini-video-analyzer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'server-only';
import { formatApiError } from '@/lib/error-handling';

/**
* Agentic Video Intelligence Engine — Gemini + Google Search grounding.
Expand Down Expand Up @@ -297,7 +298,7 @@ export async function analyzeVideoWithGemini(
const resultText = response.text || '{}';
return parseAnalysisResult(resultText);
} catch (error: unknown) {
const errorMessage = error instanceof Error ? error.message : String(error);
const errorMessage = formatApiError(error).message;
const retryable =
error instanceof AnalysisParseError ||
errorMessage.includes('503') ||
Expand Down
5 changes: 3 additions & 2 deletions apps/web/src/lib/pipeline-backend-health.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'server-only';
import { formatApiError } from '@/lib/error-handling';

import { backendHeaders } from '@/lib/pipeline-backend';

Expand Down Expand Up @@ -63,7 +64,7 @@ export async function checkBackendHealth(
configured: true,
available: false,
host: backendHost(url),
reason: error instanceof Error ? error.message : String(error),
reason: formatApiError(error).message,
};
}
}
Expand All @@ -80,4 +81,4 @@ export async function parseBackendJson<T>(response: Response): Promise<T | null>
} catch {
return null;
}
}
}
9 changes: 5 additions & 4 deletions apps/web/src/lib/transcription-service-improved.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'server-only';
import { formatApiError } from '@/lib/error-handling';

import OpenAI from 'openai';
import { fetchYouTubeMetadata, formatMetadataAsContext } from '@/lib/youtube-metadata';
Expand Down Expand Up @@ -125,7 +126,7 @@ export async function fetchTranscript({
} catch (error) {
console.warn(
'Backend transcript unavailable:',
error instanceof Error ? error.message : String(error)
formatApiError(error).message
);
// Continue to fallback strategies
}
Expand All @@ -143,7 +144,7 @@ export async function fetchTranscript({
} catch (error) {
console.warn(
'YouTube metadata fetch failed:',
error instanceof Error ? error.message : String(error)
formatApiError(error).message
);
// Continue without metadata
}
Expand Down Expand Up @@ -207,7 +208,7 @@ INSTRUCTIONS:
};
}
} catch (error) {
const errorMsg = error instanceof Error ? error.message : String(error);
const errorMsg = formatApiError(error).message;
console.warn('Gemini transcription failed:', errorMsg);

// Handle specific errors
Expand Down Expand Up @@ -262,7 +263,7 @@ Be thorough — capture all key points, quotes, technical details, and chapter b
};
}
} catch (error) {
const errorMsg = error instanceof Error ? error.message : String(error);
const errorMsg = formatApiError(error).message;
console.warn('OpenAI transcription failed:', errorMsg);

if (errorMsg.includes('429')) {
Expand Down
Loading