From 07cdaafcb20606b36318946179a8415ec7c5c99a Mon Sep 17 00:00:00 2001 From: katelya Date: Fri, 5 Sep 2025 16:05:52 +0800 Subject: [PATCH] Fix 500 Internal Server Error: Add error handling for D1 database access in Cloudflare Pages --- src/app/layout.tsx | 19 +++++++++++++------ src/lib/config.ts | 26 ++++++++++++++++++-------- src/lib/d1.db.ts | 17 ++++++++++++++++- 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/src/app/layout.tsx b/src/app/layout.tsx index c4c722d..01527c4 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -14,12 +14,19 @@ const inter = Inter({ subsets: ['latin'] }); // 动态生成 metadata,支持配置更新后的标题变化 export async function generateMetadata(): Promise { let siteName = process.env.SITE_NAME || 'KatelyaTV'; - if ( - process.env.NEXT_PUBLIC_STORAGE_TYPE !== 'd1' && - process.env.NEXT_PUBLIC_STORAGE_TYPE !== 'upstash' - ) { - const config = await getConfig(); - siteName = config.SiteConfig.SiteName; + + try { + // 只有在非 d1 和 upstash 存储类型时才尝试获取配置 + if ( + process.env.NEXT_PUBLIC_STORAGE_TYPE !== 'd1' && + process.env.NEXT_PUBLIC_STORAGE_TYPE !== 'upstash' + ) { + const config = await getConfig(); + siteName = config.SiteConfig.SiteName; + } + } catch (error) { + // 如果配置获取失败,使用默认站点名称 + // siteName 已经有默认值,不需要额外处理 } return { diff --git a/src/lib/config.ts b/src/lib/config.ts index b3e33ad..2fdcf1f 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -225,19 +225,24 @@ async function initConfig() { export async function getConfig(): Promise { const storageType = process.env.NEXT_PUBLIC_STORAGE_TYPE || 'localstorage'; + if (process.env.DOCKER_ENV === 'true' || storageType === 'localstorage') { await initConfig(); return cachedConfig; } + // 非 docker 环境且 DB 存储,直接读 db 配置 - const storage = getStorage(); - let adminConfig: AdminConfig | null = null; - if (storage && typeof (storage as any).getAdminConfig === 'function') { - adminConfig = await (storage as any).getAdminConfig(); - } - if (adminConfig) { - // 合并一些环境变量配置 - adminConfig.SiteConfig.SiteName = process.env.SITE_NAME || 'KatelyaTV'; + try { + const storage = getStorage(); + let adminConfig: AdminConfig | null = null; + + if (storage && typeof (storage as any).getAdminConfig === 'function') { + adminConfig = await (storage as any).getAdminConfig(); + } + + if (adminConfig) { + // 合并一些环境变量配置 + adminConfig.SiteConfig.SiteName = process.env.SITE_NAME || 'KatelyaTV'; adminConfig.SiteConfig.Announcement = process.env.ANNOUNCEMENT || '本网站仅提供影视信息搜索服务,所有内容均来自第三方网站。本站不存储任何视频资源,不对任何内容的准确性、合法性、完整性负责。'; @@ -306,6 +311,11 @@ export async function getConfig(): Promise { await initConfig(); } return cachedConfig; + } catch (error) { + // 如果数据库访问失败,回退到默认配置 + await initConfig(); + return cachedConfig; + } } export async function resetConfig() { diff --git a/src/lib/d1.db.ts b/src/lib/d1.db.ts index 4cb53fc..172785e 100644 --- a/src/lib/d1.db.ts +++ b/src/lib/d1.db.ts @@ -39,7 +39,22 @@ interface D1ExecResult { // 获取全局D1数据库实例 function getD1Database(): D1Database { - return (process.env as any).DB as D1Database; + // 在 Cloudflare Pages/Workers 环境中,DB 是全局变量 + if (typeof globalThis !== 'undefined' && (globalThis as any).DB) { + return (globalThis as any).DB as D1Database; + } + + // 回退到 process.env(用于本地开发) + if ((process.env as any).DB) { + return (process.env as any).DB as D1Database; + } + + // 最后尝试从 globalThis.process.env + if (typeof globalThis !== 'undefined' && (globalThis as any).process?.env?.DB) { + return (globalThis as any).process.env.DB as D1Database; + } + + throw new Error('D1 database not available. Make sure DB binding is configured.'); } export class D1Storage implements IStorage {