errorResult
Small helpers for tool results and failures.
Small helpers for tool results and failures. errorResult turns a caught error into a coded isError result the agent can read and recover from; the others normalise return values, read error text, and tell cancellation apart from failure. Reach for them when you write the glue between your own code and document.modelContext; a tool made with defineWebTool already does all of this.
Import
import {
errorResult,
errorText,
isAbortError,
isErrorText,
toToolResult,
} from "@webmcp-agents/core";
Example
A call wrapper: a result becomes MCP content, a failure becomes a coded error, and a cancellation stays a rejection.
import {
errorResult,
isAbortError,
toToolResult,
WebToolError,
} from "@webmcp-agents/core";
async function placeOrder(id: string, signal: AbortSignal) {
if (signal.aborted) throw signal.reason;
if (id === "") throw new WebToolError("invalid_input", "Empty id");
return { order: id };
}
export async function call(id: string, signal: AbortSignal) {
try {
// An object becomes JSON text; a string becomes text.
return toToolResult(await placeOrder(id, signal));
} catch (err) {
// Cancellation must reject, never become a result.
if (isAbortError(err)) throw err;
// "Error [invalid_input]: Empty id", isError: true
return errorResult(err);
}
}
A form that shows and answers with the same message uses errorText:
import { errorText } from "@webmcp-agents/core";
function failed(err: unknown, setError: (text: string) => void) {
setError(errorText(err)); // on the page
return `Error: ${errorText(err)}`; // to the agent
}
Options
Each helper takes only positional arguments.
| Name | Type | Default | Description |
|---|---|---|---|
errorResult(err, code?) |
(err: unknown, code?: ToolErrorCode) => ModelContextToolResult |
code: "failed" |
A failure the agent can read. err is what was thrown; code is used when err is not a WebToolError, which brings its own. |
errorText(err) |
(err: unknown) => string |
required | The message of what was thrown: err.message for an Error, String(err) for anything else. |
isErrorText(text) |
(text: string) => boolean |
required | Whether a result’s text reads as a failure: it starts with Error: or Error [code]:. |
isAbortError(err) |
(err: unknown) => boolean |
required | Whether what was thrown is a cancellation (err.name === "AbortError"). |
toToolResult(value) |
(value: unknown) => ModelContextToolResult |
required | Normalise what a tool returned into an MCP result. |
Returns
| Function | Returns |
|---|---|
errorResult |
toolError(code, errorText(err)): { content: [{ type: "text", text: "Error [code]: …" }], isError: true }, using the WebToolError’s code when err is one. |
errorText |
A string. |
isErrorText |
A boolean. |
isAbortError |
A boolean. |
toToolResult |
An MCP result: a string becomes text content, an object (not already a result) becomes JSON text, a value with a content array passes through, null or undefined becomes { content: [] }. |
Notes
isErrorTextexists because declarative forms cannot setisError, so they answer withError: …text.@webmcp-agents/devtoolstreats a result as failed whenisErroris set orisErrorTextmatches its text.toToolResultapplies the same rules the polyfill applies to imperative tools.- Cancellation must propagate as a rejection: check
isAbortErrorbefore turning an error into a result.