diff --git a/src/main/services/FileStorage.ts b/src/main/services/FileStorage.ts index 3165fcf27..5b8fd5c13 100644 --- a/src/main/services/FileStorage.ts +++ b/src/main/services/FileStorage.ts @@ -485,6 +485,12 @@ class FileStorage { ): Promise => { const filePath = path.join(this.storageDir, id) + // 先检查文件是否存在,避免 ENOENT 错误 + if (!fs.existsSync(filePath)) { + logger.debug(`File not found: ${filePath}`) + throw new Error(`ENOENT: no such file or directory, open '${id}'`) + } + const fileExtension = path.extname(filePath) if (documentExts.includes(fileExtension)) { diff --git a/src/renderer/src/components/MinApp/MinApp.tsx b/src/renderer/src/components/MinApp/MinApp.tsx index b6a623d30..c81784358 100644 --- a/src/renderer/src/components/MinApp/MinApp.tsx +++ b/src/renderer/src/components/MinApp/MinApp.tsx @@ -87,8 +87,27 @@ const MinApp: FC = ({ app, onClick, size = 60, isLast }) => { danger: true, onClick: async () => { try { - const content = await window.api.file.read('custom-minapps.json') - const customApps = JSON.parse(content) + let content: string + let customApps: MinAppType[] + + try { + content = await window.api.file.read('custom-minapps.json') + customApps = JSON.parse(content) + // 确保解析结果是数组 + if (!Array.isArray(customApps)) { + customApps = [] + } + } catch (error: any) { + // 如果文件不存在或解析失败,使用空数组 + if (error.message?.includes('ENOENT') || error.message?.includes('no such file')) { + customApps = [] + } else { + // 其他解析错误,使用空数组 + logger.warn('Failed to read custom-minapps.json, using empty array:', error as Error) + customApps = [] + } + } + const updatedApps = customApps.filter((customApp: MinAppType) => customApp.id !== app.id) await window.api.file.writeWithId('custom-minapps.json', JSON.stringify(updatedApps, null, 2)) window.toast.success(t('settings.miniapps.custom.remove_success')) diff --git a/src/renderer/src/config/minapps.ts b/src/renderer/src/config/minapps.ts index 815b3f476..1434b8433 100644 --- a/src/renderer/src/config/minapps.ts +++ b/src/renderer/src/config/minapps.ts @@ -67,13 +67,42 @@ const loadCustomMiniApp = async (): Promise => { let content: string try { content = await window.api.file.read('custom-minapps.json') - } catch (error) { + } catch (error: any) { // 如果文件不存在,创建一个空的 JSON 数组 - content = '[]' - await window.api.file.writeWithId('custom-minapps.json', content) + // 检查是否是文件不存在的错误 + if (error.message?.includes('ENOENT') || error.message?.includes('no such file')) { + content = '[]' + try { + await window.api.file.writeWithId('custom-minapps.json', content) + } catch (writeError) { + logger.warn('Failed to create custom-minapps.json file:', writeError as Error) + // 如果创建文件失败,仍然返回空数组 + } + } else { + // 其他类型的错误,记录并返回空数组 + logger.error('Failed to read custom-minapps.json:', error as Error) + return [] + } + } + + // 确保内容有效 + if (!content || content.trim() === '') { + content = '[]' + } + + let customApps: any[] + try { + customApps = JSON.parse(content) + // 确保解析结果是数组 + if (!Array.isArray(customApps)) { + logger.warn('custom-minapps.json content is not an array, using empty array') + customApps = [] + } + } catch (parseError) { + logger.error('Failed to parse custom-minapps.json content:', parseError as Error) + customApps = [] } - const customApps = JSON.parse(content) const now = new Date().toISOString() return customApps.map((app: any) => ({ diff --git a/src/renderer/src/pages/home/Messages/MessageGroup.tsx b/src/renderer/src/pages/home/Messages/MessageGroup.tsx index 0f5a7e83f..4b7f59d52 100644 --- a/src/renderer/src/pages/home/Messages/MessageGroup.tsx +++ b/src/renderer/src/pages/home/Messages/MessageGroup.tsx @@ -11,7 +11,8 @@ import type { Topic } from '@renderer/types' import type { Message } from '@renderer/types/newMessage' import { classNames } from '@renderer/utils' import { Popover } from 'antd' -import { ComponentProps, memo, useCallback, useEffect, useMemo, useState } from 'react' +import type { ComponentProps} from 'react'; +import { memo, useCallback, useEffect, useMemo, useState } from 'react' import styled from 'styled-components' import { useChatMaxWidth } from '../Chat' diff --git a/src/renderer/src/pages/minapps/NewAppButton.tsx b/src/renderer/src/pages/minapps/NewAppButton.tsx index 22d9f9345..72ea94e32 100644 --- a/src/renderer/src/pages/minapps/NewAppButton.tsx +++ b/src/renderer/src/pages/minapps/NewAppButton.tsx @@ -32,8 +32,26 @@ const NewAppButton: FC = ({ size = 60 }) => { const handleAddCustomApp = async (values: any) => { try { - const content = await window.api.file.read('custom-minapps.json') - const customApps = JSON.parse(content) + let content: string + let customApps: MinAppType[] + + try { + content = await window.api.file.read('custom-minapps.json') + customApps = JSON.parse(content) + // 确保解析结果是数组 + if (!Array.isArray(customApps)) { + customApps = [] + } + } catch (error: any) { + // 如果文件不存在或解析失败,使用空数组 + if (error.message?.includes('ENOENT') || error.message?.includes('no such file')) { + customApps = [] + } else { + // 其他解析错误,使用空数组 + logger.warn('Failed to read custom-minapps.json, using empty array:', error as Error) + customApps = [] + } + } // Check for duplicate ID if (customApps.some((app: MinAppType) => app.id === values.id)) {