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:
Ivan Pereira
2026-02-23 10:49:33 +00:00
parent 2c5b558271
commit 63eb22316a
2 changed files with 19 additions and 14 deletions
+17 -5
View File
@@ -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 },
};
}
},
+2 -9
View File
@@ -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);
}