summaryrefslogtreecommitdiff
path: root/src/errors.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/errors.ts')
-rw-r--r--src/errors.ts37
1 files changed, 32 insertions, 5 deletions
diff --git a/src/errors.ts b/src/errors.ts
index d003e4f..2318b27 100644
--- a/src/errors.ts
+++ b/src/errors.ts
@@ -19,15 +19,35 @@ export class SearchChallengeError extends Error {
readonly pageUrl: string;
/** Which browser is blocked, e.g. "10.88.0.25:9223 (built-in default)". */
readonly endpoint: string;
+ /** Which engine is blocked. */
+ readonly engine: string;
+ /** Engines that are not blocked and could be tried instead. */
+ readonly alternatives: readonly string[];
- constructor(options: { challenge: string; pageUrl: string; endpoint: string; detail?: string | undefined }) {
+ constructor(options: {
+ challenge: string;
+ pageUrl: string;
+ endpoint: string;
+ engine: string;
+ alternatives: readonly string[];
+ detail?: string | undefined;
+ }) {
super(
[
- `Search is blocked by a human verification challenge (${options.challenge}).`,
+ `${options.engine} is blocked by a human verification challenge (${options.challenge}).`,
options.detail ? `Page said: ${options.detail}` : null,
- `This cannot be solved by the agent — a person has to clear it in the browser at ${options.endpoint}.`,
- `Ask the user to open ${options.pageUrl} in that Chrome, complete the challenge or accept the consent dialog,`,
- `then retry the search. The cookie it sets persists in that browser profile, so one pass unblocks later searches.`,
+ // Retrying elsewhere comes first because it is the action the agent can
+ // take on its own; a challenge on one engine says nothing about the
+ // others, and asking the operator for help should be the fallback, not
+ // the first move.
+ options.alternatives.length > 0
+ ? `A challenge on one engine does not affect the others: retry the same query with engine set to ` +
+ `${options.alternatives.join(", ")} before asking anyone for help.`
+ : null,
+ `If every engine is blocked, this needs a person — the challenge cannot be solved by the agent.`,
+ `Ask the user to open ${options.pageUrl} in the Chrome at ${options.endpoint}, complete the challenge or`,
+ `accept the consent dialog, then retry. The cookie it sets persists in that browser profile, so one pass`,
+ `unblocks later searches.`,
]
.filter((line) => line !== null)
.join(" "),
@@ -35,9 +55,16 @@ export class SearchChallengeError extends Error {
this.challenge = options.challenge;
this.pageUrl = options.pageUrl;
this.endpoint = options.endpoint;
+ this.engine = options.engine;
+ this.alternatives = options.alternatives;
}
}
+/** The chosen engine cannot express the requested recency window. */
+export class RecencyUnsupportedError extends Error {
+ override readonly name = "RecencyUnsupportedError";
+}
+
/** The browser could not be reached or spoke CDP badly. */
export class BrowserUnavailableError extends Error {
override readonly name = "BrowserUnavailableError";