fix(chart): add detailed error logging to debug 500 error
- Add step-by-step console logging in API route - Show actual error message in dialog - Add debug info section - Wrap each section in try-catch to isolate failure point
This commit is contained in:
@@ -32,21 +32,28 @@ interface SuggestChartsResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function POST(req: Request) {
|
export async function POST(req: Request) {
|
||||||
|
console.log('[suggest-charts] ===== REQUEST START =====')
|
||||||
|
|
||||||
// 1. Auth check
|
// 1. Auth check
|
||||||
const session = await auth()
|
const session = await auth()
|
||||||
if (!session?.user?.id) {
|
if (!session?.user?.id) {
|
||||||
|
console.error('[suggest-charts] NO SESSION')
|
||||||
return new Response('Unauthorized', { status: 401 })
|
return new Response('Unauthorized', { status: 401 })
|
||||||
}
|
}
|
||||||
const userId = session.user.id
|
const userId = session.user.id
|
||||||
|
console.log('[suggest-charts] userId:', userId)
|
||||||
|
|
||||||
// 1.5 Quota check
|
// 1.5 Quota check
|
||||||
try {
|
try {
|
||||||
const sysConfigEarly = await getSystemConfig()
|
const sysConfigEarly = await getSystemConfig()
|
||||||
const { usedByok: willUseByok } = await willUseByokForLane('suggest-charts', sysConfigEarly, userId)
|
const { usedByok: willUseByok } = await willUseByokForLane('suggest-charts', sysConfigEarly, userId)
|
||||||
|
console.log('[suggest-charts] BYOK:', willUseByok)
|
||||||
if (!willUseByok) {
|
if (!willUseByok) {
|
||||||
await checkEntitlementOrThrow(userId, 'suggest_charts')
|
await checkEntitlementOrThrow(userId, 'suggest_charts')
|
||||||
|
console.log('[suggest-charts] Quota OK')
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
console.error('[suggest-charts] QUOTA ERROR:', err)
|
||||||
if (err instanceof QuotaExceededError) {
|
if (err instanceof QuotaExceededError) {
|
||||||
return Response.json(err.toJSON(), { status: 402 })
|
return Response.json(err.toJSON(), { status: 402 })
|
||||||
}
|
}
|
||||||
@@ -54,10 +61,24 @@ export async function POST(req: Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. Parse request body
|
// 2. Parse request body
|
||||||
const body = await req.json() as SuggestChartsRequest
|
let body: SuggestChartsRequest
|
||||||
|
try {
|
||||||
|
body = await req.json()
|
||||||
|
} catch (e) {
|
||||||
|
console.error('[suggest-charts] INVALID JSON:', e)
|
||||||
|
return Response.json({
|
||||||
|
error: 'Invalid request',
|
||||||
|
suggestions: [],
|
||||||
|
analyzedText: '',
|
||||||
|
detectedData: '',
|
||||||
|
hasData: false,
|
||||||
|
} satisfies SuggestChartsResponse, { status: 400 })
|
||||||
|
}
|
||||||
const { content, selection, noteId } = body
|
const { content, selection, noteId } = body
|
||||||
|
console.log('[suggest-charts] contentLen:', content?.length, 'selectionLen:', selection?.length)
|
||||||
|
|
||||||
if (!content || content.trim().length === 0) {
|
if (!content || content.trim().length === 0) {
|
||||||
|
console.error('[suggest-charts] EMPTY CONTENT')
|
||||||
return Response.json({
|
return Response.json({
|
||||||
error: 'Content is required',
|
error: 'Content is required',
|
||||||
suggestions: [],
|
suggestions: [],
|
||||||
@@ -68,10 +89,26 @@ export async function POST(req: Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const textToAnalyze = selection && selection.trim() ? selection.trim() : content.trim()
|
const textToAnalyze = selection && selection.trim() ? selection.trim() : content.trim()
|
||||||
|
console.log('[suggest-charts] analyzeLen:', textToAnalyze.length, 'preview:', textToAnalyze.substring(0, 100))
|
||||||
|
|
||||||
// 3. Build AI context
|
// 3. Build AI context
|
||||||
const sysConfig = await getSystemConfig()
|
let sysConfig, provider, model
|
||||||
const { provider, model, timingInfo } = await resolveAiRouteWithTiming('suggest-charts', sysConfig)
|
try {
|
||||||
|
sysConfig = await getSystemConfig()
|
||||||
|
const result = await resolveAiRouteWithTiming('suggest-charts', sysConfig)
|
||||||
|
provider = result.provider
|
||||||
|
model = result.model
|
||||||
|
console.log('[suggest-charts] AI model:', model)
|
||||||
|
} catch (e) {
|
||||||
|
console.error('[suggest-charts] AI ROUTE ERROR:', e)
|
||||||
|
return Response.json({
|
||||||
|
error: 'AI service unavailable: ' + (e instanceof Error ? e.message : String(e)),
|
||||||
|
suggestions: [],
|
||||||
|
analyzedText: textToAnalyze.substring(0, 100),
|
||||||
|
detectedData: '',
|
||||||
|
hasData: false,
|
||||||
|
} satisfies SuggestChartsResponse, { status: 500 })
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 4. Call AI to analyze and suggest - direct JSON response (no tool)
|
// 4. Call AI to analyze and suggest - direct JSON response (no tool)
|
||||||
@@ -206,12 +243,15 @@ Response format (COPY this structure):
|
|||||||
return Response.json(parsed satisfies SuggestChartsResponse)
|
return Response.json(parsed satisfies SuggestChartsResponse)
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[suggest-charts] Error:', error)
|
console.error('[suggest-charts] ===== MAIN ERROR =====')
|
||||||
|
console.error('[suggest-charts] Error name:', error instanceof Error ? error.name : typeof error)
|
||||||
|
console.error('[suggest-charts] Error message:', error instanceof Error ? error.message : String(error))
|
||||||
|
console.error('[suggest-charts] Error stack:', error instanceof Error ? error.stack : 'no stack')
|
||||||
return Response.json({
|
return Response.json({
|
||||||
error: 'Failed to generate chart suggestions',
|
error: 'Failed: ' + (error instanceof Error ? error.message : String(error)),
|
||||||
suggestions: [],
|
suggestions: [],
|
||||||
analyzedText: textToAnalyze.substring(0, 100),
|
analyzedText: textToAnalyze?.substring(0, 100) || '',
|
||||||
detectedData: 'Error occurred during analysis',
|
detectedData: 'Error occurred',
|
||||||
hasData: false,
|
hasData: false,
|
||||||
} satisfies SuggestChartsResponse, { status: 500 })
|
} satisfies SuggestChartsResponse, { status: 500 })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -176,7 +176,14 @@ export function ChartSuggestionsDialog({
|
|||||||
<div className="text-center max-w-md">
|
<div className="text-center max-w-md">
|
||||||
<AlertCircle className="w-12 h-12 mx-auto mb-4 text-destructive" />
|
<AlertCircle className="w-12 h-12 mx-auto mb-4 text-destructive" />
|
||||||
<h3 className="text-lg font-semibold mb-2">Error</h3>
|
<h3 className="text-lg font-semibold mb-2">Error</h3>
|
||||||
<p className="text-muted-foreground">{response.error}</p>
|
<p className="text-sm text-muted-foreground mb-2">{response.error}</p>
|
||||||
|
<details className="text-left text-xs text-muted-foreground mt-4">
|
||||||
|
<summary className="cursor-pointer hover:text-foreground">Debug info</summary>
|
||||||
|
<pre className="mt-2 bg-muted p-2 rounded overflow-auto max-h-32">
|
||||||
|
analyzedText: {response.analyzedText}
|
||||||
|
{'\n'}detectedData: {response.detectedData}
|
||||||
|
</pre>
|
||||||
|
</details>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : !response?.hasData ? (
|
) : !response?.hasData ? (
|
||||||
|
|||||||
Reference in New Issue
Block a user