/** * Typed error hierarchy for gws CLI errors. * * Ported from podcastindex-mcp's typed-error pattern (v0.3.0), but adapted to * a different boundary: podcastindex-mcp wraps an axios HTTP client, so it * maps `error.response.status` straight to a typed error. gws-mcp-server has * no HTTP client of its own — it spawns the `gws` CLI as a subprocess (see * `executeGws()` in ./executor.ts) and only ever sees plain text: the * process's stderr/stdout, or an `Error.message` string from a rejected * spawn promise. There is no `.status` field to read. * * `mapGwsErrorToTyped()` recovers a status-like code from that raw text (see * `extractGwsErrorDetail()`) and maps it to one of these classes, so callers * can branch on error type with `instanceof` instead of grepping message * strings. `executeGws()` catches the raw error, builds a typed error here, * and uses its fully-formatted `.message` as `ExecResult.error` — each * subclass builds its own human-readable message so formatting logic lives * in one place. */ export declare class GwsError extends Error { readonly status?: number; constructor(message: string, status?: number); } /** 401/403 — bad, missing, or expired gws CLI credentials. */ export declare class AuthenticationError extends GwsError { constructor(detail: string, status: number); } /** 429 — too many requests against a Google Workspace API. */ export declare class RateLimitError extends GwsError { constructor(detail: string, status: number); } /** 400 — malformed or invalid request parameters. */ export declare class ValidationError extends GwsError { constructor(detail: string, status: number); } /** * 404 — the requested resource does not exist, or isn't visible to the * authenticated account. `driveHint` preserves the original executor.ts * behavior: Drive 404s get an actionable hint about shared-drive access. */ export declare class NotFoundError extends GwsError { constructor(detail: string, status: number, driveHint?: boolean); } /** 5xx — failure on Google's side. */ export declare class ServerError extends GwsError { constructor(detail: string, status: number); } /** Result of pulling a status-like code + detail message out of raw CLI error text. */ export interface GwsErrorInfo { status?: number; detail: string; } /** * Pulls a status code + detail message out of the gws CLI's raw error text. * * There is no HTTP response object at this boundary (see module doc above) * — just a string. Google Workspace API errors surface in that string in * one of two shapes, and this applies podcastindex-mcp's "JSON vs * plain-text body" lesson to a CLI boundary instead of an HTTP one: * * 1. A raw JSON error body the CLI printed as-is. Google's own API error * shape is `{"error":{"code":404,"message":"...","errors":[...]}}` — * some CLI tools print this verbatim on failure. * 2. Plain text containing an HTTP-status-like token, e.g. "Error 403: ...", * "404 not found", "googleapi: Error 429: quota exceeded". * * If neither pattern is found, `status` is left undefined — this is the * legacy fallback: the original message is returned unchanged so callers * don't force a typed error (with invented wording) onto CLI text that * carries no recognizable status code. */ export declare function extractGwsErrorDetail(rawMessage: string): GwsErrorInfo; /** * Maps the gws CLI's raw error text to the appropriate typed error. * * `command` is the tool's `ToolDef.command` (e.g. `["drive", "files", "get"]`) * — used only to decide whether a 404 should carry the Drive shared-drive * hint that `executeGws()` used to append inline (see ./executor.ts history). * * Falls back to the base `GwsError` (message passed through unchanged) when * no status-like code can be recovered from the text — never invents a * status for CLI text that doesn't carry one. */ export declare function mapGwsErrorToTyped(rawMessage: string, command: string[]): GwsError;