{"record":{"id":"f9a10978c614a8a0","repo":"linshenkx/prompt-optimizer","slug":"validation-error","errorCode":"VALIDATION_ERROR","errorMessage":"${error.message}","messagePattern":"\\$\\{error\\.message\\}","errorType":"validation","errorClass":"FavoriteValidationError","httpStatus":null,"severity":"warning","filePath":"packages/core/src/services/favorite/electron-proxy.ts","lineNumber":62,"sourceCode":"      return await (window.electronAPI.favoriteManager as any)[method](...safeArgs);\n    } catch (error: any) {\n      // New i18n-style structured errors: pass through as-is so UI can translate via `code + params`.\n      if (typeof error?.code === 'string' && error.code.startsWith('error.')) {\n        throw toErrorWithCode(error)\n      }\n\n      // 将IPC错误转换为具体的错误类型\n      if (error.code === 'FAVORITE_NOT_FOUND') {\n        throw new FavoriteNotFoundError(error.id || '');\n      }\n      if (error.code === 'FAVORITE_ALREADY_EXISTS') {\n        throw new FavoriteAlreadyExistsError(error.content || '');\n      }\n      if (error.code === 'CATEGORY_NOT_FOUND') {\n        throw new FavoriteCategoryNotFoundError(error.id || '');\n      }\n      if (error.code === 'VALIDATION_ERROR') {\n        throw new FavoriteValidationError(error.message || '');\n      }\n      if (error.code === 'STORAGE_ERROR') {\n        throw new FavoriteStorageError(error.message || '');\n      }\n      // Legacy: category already exists\n      if (error.code === 'CATEGORY_ALREADY_EXISTS') {\n        throw new FavoriteValidationError(error.message || 'Category already exists')\n      }\n      // 标签相关错误\n      if (error.code === 'TAG_ALREADY_EXISTS') {\n        throw new FavoriteTagAlreadyExistsError(error.tag || '');\n      }\n      if (error.code === 'TAG_NOT_FOUND') {\n        throw new FavoriteTagNotFoundError(error.tag || '');\n      }\n      if (error.code === 'TAG_ERROR') {\n        throw new FavoriteTagError(FAVORITE_ERROR_CODES.TAG_ERROR, error.message || '', { details: error.message || '' });\n      }","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/core/src/services/favorite/electron-proxy.ts#L44-L80","documentation":"Main process returned VALIDATION_ERROR; converted to FavoriteValidationError with the main-process message. Input failed validation rules enforced on the Electron side.","triggerScenarios":"Submitting a favorite payload that fails main-process validation (empty fields, bad enums, oversized metadata) through any proxy method.","commonSituations":"Renderer-side validation skipped or out of sync with stricter main-process rules; version skew between renderer and main; malformed imported data passed through directly.","solutions":["Log and display the error.message — it states which rule failed","Mirror the main-process validation rules in the renderer form","Update renderer and main to the same package version so validation rules match","Sanitize imported data before passing it to addFavorite"],"exampleFix":"// before\nawait mgr.addFavorite(raw);\n// after\nif (!raw.content?.trim()) throw new Error('content required');\nawait mgr.addFavorite(raw);","handlingStrategy":"validation","validationCode":"function validateFavoriteInput(f: Partial<FavoritePrompt>): string[] {\n  const errs: string[] = [];\n  if (!f.content?.trim()) errs.push('content required');\n  if (!f.functionMode) errs.push('functionMode required');\n  return errs;\n}","typeGuard":"const isFavoriteValidation = (e: unknown): e is FavoriteValidationError => e instanceof FavoriteValidationError;","tryCatchPattern":"try { await mgr.addFavorite(fav); } catch (e) { if (isFavoriteValidation(e)) { showFormError(e.message); return; } throw e; }","preventionTips":["Mirror main-process rules in renderer forms","Keep renderer and main package versions in lockstep","Run validateFavoriteInput before any proxy call"],"tags":["favorite","validation","ipc","electron"],"backgroundTag":"input-validation-failed","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}