{"record":{"id":"409f514d82daa073","repo":"linshenkx/prompt-optimizer","slug":"custom-conversation-test-failed-errormessage","errorCode":null,"errorMessage":"Custom conversation test failed: ${errorMessage}","messagePattern":"Custom conversation test failed: (.+?)","errorType":"exception","errorClass":"TestError","httpStatus":null,"severity":"error","filePath":"packages/core/src/services/prompt/service.ts","lineNumber":1200,"sourceCode":"            },\n          },\n        );\n      }\n    } catch (error) {\n      const errorMessage =\n        error instanceof Error ? error.message : String(error);\n      console.error(\n        \"[PromptService] Custom conversation test error:\",\n        errorMessage,\n      );\n\n      // 通过回调传递错误\n      if (callbacks.onError) {\n        callbacks.onError(\n          new Error(`Custom conversation test failed: ${errorMessage}`),\n        );\n        } else {\n          throw new TestError(\n            \"\",\n            \"\",\n            `Custom conversation test failed: ${errorMessage}`,\n          );\n        }\n    }\n  }\n}\n","sourceCodeStart":1182,"sourceCodeEnd":1209,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/core/src/services/prompt/service.ts#L1182-L1209","documentation":"Wrapper error reported when the underlying LLM streaming call (sendMessageStreamWithTools or the plain stream) throws during a custom conversation test. The original error message is embedded in the message; if no onError callback is registered it is rethrown as a TestError, otherwise it is delivered to callbacks.onError.","triggerScenarios":"Any failure inside the streaming LLM call: invalid API key, network failure, provider 4xx/5xx, malformed tool definitions, or the model rejecting the message array. The catch block wraps it as 'Custom conversation test failed: <original message>'.","commonSituations":"Expired/missing API key; rate limits; wrong base URL for a self-hosted provider; tool schema the model rejects; network offline in an Electron/webview environment.","solutions":["Read the embedded original message — it identifies the real cause (auth, network, schema)","Check provider credentials and connectivity (key valid, base URL reachable)","Validate tool definitions against the provider's schema before testing","Register callbacks.onError so the failure surfaces in your UI instead of an unhandled throw"],"exampleFix":"// before\nawait svc.testCustomConversationStream(req); // throws TestError\n\n// after\nawait svc.testCustomConversationStream(req, {\n  onError: (e) => logger.error('test failed', e.message),\n});","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"null","tryCatchPattern":"try {\n  await svc.testCustomConversationStream(req, { onError: (err) => ui.showToast(err.message) });\n} catch (e) {\n  if (e instanceof TestError && e.message.startsWith('Custom conversation test failed:')) {\n    const cause = e.message.split(':').slice(1).join(':').trim(); // real LLM error\n    handleLlmFailure(cause);\n  } else throw e;\n}","preventionTips":["Always pass callbacks.onError so failures route to your UI instead of throwing","Validate tool schemas and credentials before initiating a test","Parse the embedded original message rather than guessing at the wrapper text"],"tags":["llm","streaming","error-wrapping"],"backgroundTag":"llm-api-request-failed","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}