Replace brittle error text detection with isError flag
renderPerplexityResult was pattern-matching content text prefixes to decide whether to render in error style. This was tightly coupled to exact message strings in index.ts — a wording change would silently break the error styling. Set isError: true in details on every error return path in execute, and check details.isError in the renderer instead.
This commit is contained in:
+17
-5
@@ -5,7 +5,7 @@ import { Type } from "@sinclair/typebox";
|
||||
import { registerPerplexityCommands } from "./commands/login.js";
|
||||
|
||||
import { authenticate } from "./auth/login.js";
|
||||
import { clearToken } from "./auth/storage.js";
|
||||
|
||||
import { formatForLLM } from "./search/format.js";
|
||||
import { searchPerplexity } from "./search/client.js";
|
||||
import { renderPerplexityCall } from "./render/call.js";
|
||||
@@ -99,17 +99,29 @@ export default function (pi: ExtensionAPI) {
|
||||
if (error instanceof AuthError) {
|
||||
return {
|
||||
content: [{ type: "text", text: `Authentication failed: ${error.message}` }],
|
||||
details: { sourceCount, queryMs },
|
||||
details: { sourceCount, queryMs, isError: true },
|
||||
};
|
||||
}
|
||||
|
||||
if (error instanceof SearchError) {
|
||||
if (error.code === "AUTH") {
|
||||
await clearToken().catch(() => undefined);
|
||||
// Do NOT clear the token here. The user must re-login explicitly via
|
||||
// /perplexity-login --force. Clearing automatically would silently discard
|
||||
// a token that may still be valid (e.g. a transient 401), and removes the
|
||||
// user's ability to inspect or recover the cached credential themselves.
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: `Perplexity authentication failed. Run /perplexity-login --force to re-authenticate.`,
|
||||
},
|
||||
],
|
||||
details: { sourceCount, queryMs, isError: true },
|
||||
};
|
||||
}
|
||||
return {
|
||||
content: [{ type: "text", text: `Perplexity search failed: ${error.message}` }],
|
||||
details: { sourceCount, queryMs },
|
||||
details: { sourceCount, queryMs, isError: true },
|
||||
};
|
||||
}
|
||||
|
||||
@@ -120,7 +132,7 @@ export default function (pi: ExtensionAPI) {
|
||||
text: `Perplexity search failed: ${errorMessage(error)}`,
|
||||
},
|
||||
],
|
||||
details: { sourceCount, queryMs },
|
||||
details: { sourceCount, queryMs, isError: true },
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
@@ -9,6 +9,7 @@ interface PerplexityResultDetails {
|
||||
uuid?: unknown;
|
||||
toolCallId?: unknown;
|
||||
error?: unknown;
|
||||
isError?: unknown;
|
||||
}
|
||||
function extractTextContent(result: AgentToolResult<PerplexityResultDetails>): string | undefined {
|
||||
if (!Array.isArray(result?.content)) {
|
||||
@@ -34,14 +35,6 @@ function extractTextContent(result: AgentToolResult<PerplexityResultDetails>): s
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isErrorText(text: string | undefined): boolean {
|
||||
if (!text) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return text.startsWith("Authentication failed:") || text.startsWith("Perplexity search failed:");
|
||||
}
|
||||
|
||||
export function renderPerplexityResult(
|
||||
result: AgentToolResult<PerplexityResultDetails>,
|
||||
options: ToolRenderResultOptions,
|
||||
@@ -69,7 +62,7 @@ export function renderPerplexityResult(
|
||||
return new Text(theme.fg("error", `Perplexity error: ${error}`), 0, 0);
|
||||
}
|
||||
|
||||
if (isErrorText(contentText)) {
|
||||
if (details.isError === true) {
|
||||
return new Text(theme.fg("error", truncate(contentText ?? "Perplexity request failed", 200)), 0, 0);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user