{"record":{"id":"74e296b0430bfa15","repo":"linshenkx/prompt-optimizer","slug":"connection-test-failed-error-message","errorCode":null,"errorMessage":"Connection test failed: ${error.message}","messagePattern":"Connection test failed: (.+?)","errorType":"exception","errorClass":"APIError","httpStatus":null,"severity":"error","filePath":"packages/core/src/services/llm/service.ts","lineNumber":228,"sourceCode":"      const testMessages: Message[] = [\n        {\n          role: 'user',\n          content: 'Please reply ok'\n        }\n      ];\n\n      this.validateMessages(testMessages);\n\n      // Send directly through the adapter to avoid the normal \"enabled\" constraint.\n      const adapter = this.registry.getAdapter(modelConfig.providerMeta.id);\n      const runtimeConfig = this.prepareRuntimeConfig(modelConfig);\n      await adapter.sendMessage(testMessages, runtimeConfig);\n\n    } catch (error: any) {\n      if (error instanceof RequestConfigError || error instanceof APIError) {\n        throw error;\n      }\n      throw new APIError(`Connection test failed: ${error.message}`);\n    }\n  }\n\n  /**\n   * 获取模型列表，以下拉选项格式返回\n   * @param provider 提供商标识\n   * @param customConfig 自定义配置（可选）\n   */\n  async fetchModelList(\n    provider: string,\n    customConfig?: Partial<TextModelConfig> | Partial<ModelConfig>\n  ): Promise<ModelOption[]> {\n    try {\n      // 获取基础配置\n      const baseConfig = await this.modelManager.getModel(provider);\n      const modelConfig = await this.buildEffectiveModelConfig(provider, baseConfig, customConfig);\n\n      // 使用 Registry 获取模型列表","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/core/src/services/llm/service.ts#L210-L246","documentation":"Thrown by LLMService.testConnection when the adapter's sendMessage call fails with an error that is not already a RequestConfigError or APIError. The raw error is wrapped into an APIError with a 'Connection test failed' prefix, meaning the configured model/provider endpoint could not be reached or rejected the test message.","triggerScenarios":"Calling llmService.testConnection(provider, modelConfig) when the provider endpoint is unreachable, the API key is rejected at the network layer, or the adapter throws a non-APIError (e.g. TypeError, fetch failure, timeout).","commonSituations":"Wrong baseUrl in model config, expired API key, network/proxy issues, CORS in browser environments, or a malformed test message built from model parameters.","solutions":["Verify the provider baseUrl and API key in the model config are correct and reachable","Test the same credentials with curl or the provider's playground","Check for proxy/firewall/CORS restrictions in the runtime environment","If a timeout or TypeError occurs, inspect error.message from the caught APIError for the underlying cause"],"exampleFix":"// before\nconst config = { ...modelConfig, baseUrl: 'https://api.example/com/v1' };\nawait service.testConnection('openai', config);\n\n// after\nconst config = { ...modelConfig, baseUrl: 'https://api.example.com/v1' };\ntry {\n  await service.testConnection('openai', config);\n} catch (e) {\n  if (e instanceof APIError) console.error('Connection test failed:', e.message);\n}","handlingStrategy":"try-catch","validationCode":"const cfgValid = Boolean(modelConfig?.baseUrl && modelConfig?.apiKey);","typeGuard":"function isAPIError(e: unknown): e is APIError { return e instanceof APIError; }","tryCatchPattern":"try { await service.testConnection(p, cfg); } catch (e) { if (e instanceof APIError) showUserMessage(e.message); else throw e; }","preventionTips":["Validate baseUrl/apiKey before testing","Surface testConnection errors in settings UI for fast feedback"],"tags":["llm","connection-test","network","api-error"],"backgroundTag":"llm-api-connection-failed","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}