🔧 Improvements: - Add /api/health endpoint for basic API functionality testing - Improve /api/test-db with timeout handling and better error reporting - Add environment variable checks before database operations - Add connection timeouts to prevent function timeouts - Better error handling and logging 🧪 Testing Endpoints: - /api/health - Simple API health check (no DB required) - /api/test-db - Database connectivity test with timeout protection These changes should help identify whether the issue is with API routing, environment variables, or database connectivity.
111 lines
No EOL
3.3 KiB
TypeScript
111 lines
No EOL
3.3 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import { Pool } from 'pg';
|
|
|
|
export default async function handler(req: NextRequest) {
|
|
if (req.method !== 'GET') {
|
|
return new NextResponse(JSON.stringify({ error: 'Method not allowed' }), {
|
|
status: 405,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
});
|
|
}
|
|
|
|
// Check environment variables first
|
|
if (!process.env.DATABASE_URL) {
|
|
return new NextResponse(JSON.stringify({
|
|
success: false,
|
|
error: 'DATABASE_URL environment variable not set',
|
|
environment: process.env.NODE_ENV || 'unknown'
|
|
}), {
|
|
status: 500,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
});
|
|
}
|
|
|
|
const pool = new Pool({
|
|
connectionString: process.env.DATABASE_URL,
|
|
ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false,
|
|
connectionTimeoutMillis: 10000, // 10 seconds
|
|
query_timeout: 10000, // 10 seconds
|
|
});
|
|
|
|
let client: any;
|
|
|
|
try {
|
|
console.log('Testing database connection...');
|
|
|
|
// Set a timeout for the entire operation
|
|
const timeoutPromise = new Promise((_, reject) => {
|
|
setTimeout(() => reject(new Error('Database operation timed out')), 15000);
|
|
});
|
|
|
|
const dbOperation = async () => {
|
|
client = await pool.connect();
|
|
|
|
// Test basic connection
|
|
const result = await client.query('SELECT NOW() as current_time, version() as postgres_version');
|
|
|
|
// Check if users table exists
|
|
const tableCheck = await client.query(`
|
|
SELECT EXISTS (
|
|
SELECT FROM information_schema.tables
|
|
WHERE table_schema = 'public'
|
|
AND table_name = 'users'
|
|
) as users_table_exists;
|
|
`);
|
|
|
|
// Check if cards table exists
|
|
const cardsCheck = await client.query(`
|
|
SELECT EXISTS (
|
|
SELECT FROM information_schema.tables
|
|
WHERE table_schema = 'public'
|
|
AND table_name = 'cards'
|
|
) as cards_table_exists;
|
|
`);
|
|
|
|
return {
|
|
current_time: result.rows[0].current_time,
|
|
postgres_version: result.rows[0].postgres_version,
|
|
users_table_exists: tableCheck.rows[0].users_table_exists,
|
|
cards_table_exists: cardsCheck.rows[0].cards_table_exists
|
|
};
|
|
};
|
|
|
|
const dbResult = await Promise.race([dbOperation(), timeoutPromise]);
|
|
|
|
return new NextResponse(JSON.stringify({
|
|
success: true,
|
|
message: 'Database connection successful',
|
|
database_info: dbResult
|
|
}), {
|
|
status: 200,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('Database connection failed:', error);
|
|
return new NextResponse(JSON.stringify({
|
|
success: false,
|
|
error: 'Database connection failed',
|
|
details: (error as Error).message,
|
|
database_url_exists: !!process.env.DATABASE_URL,
|
|
database_url_preview: process.env.DATABASE_URL ?
|
|
process.env.DATABASE_URL.substring(0, 20) + '...' : 'not set'
|
|
}), {
|
|
status: 500,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
});
|
|
} finally {
|
|
if (client) {
|
|
try {
|
|
client.release();
|
|
} catch (e) {
|
|
console.error('Error releasing client:', e);
|
|
}
|
|
}
|
|
try {
|
|
await pool.end();
|
|
} catch (e) {
|
|
console.error('Error ending pool:', e);
|
|
}
|
|
}
|
|
}
|