Let execute return { error } when throwOnError is false - #566
Open
andrelandgraf wants to merge 4 commits into
Open
andrelandgraf wants to merge 4 commits into
andrelandgraf wants to merge 4 commits into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Every
@neon/toolstool throwsNeonErrorwhen the Neon API returns an error. Agent frameworks usually want the failure back as a tool result the model can read, and callers who want to branch on the error have to wrap everyexecutein try/catch. There was no way to get the error as a typed value.What changed
createNeonToolsandcreateNeonTooltakethrowOnError?: boolean. Omitted ortrueis the current behavior:executereturns{ data }and throwsNeonErroron API failures. WiththrowOnError: false,executecatchesNeonErrorand returns it as{ error }, and the result type becomes{ data } | { error }. Zod input-validation failures and non-Neon exceptions still throw in both modes.The envelope wraps outside
onExecute, so anonExecuteinterceptor still observes the thrownNeonErrorbefore it becomes a value.Interface
The
{ data, error }destructure works because the literalthrowOnError: falsenarrows the result to the envelope union. When the options object is annotated asCreateNeonToolsOptions,throwOnErrorstays optional andexecutetypes both outcomes; narrow with"error" in result:Adapters
registerNeonTools(both@neon/tools/mcpand@neon/tools/mcp-v1),toEveToolandtoMastraToolsaccept envelope-typed tools. The MCP handler re-throws a returned{ error }, so an enveloped tool produces the sameisErrorMCP result as a throwing one.NeonExecutableToolis a new export: the execute-capable tool type whose result covers both throw modes. The adapters type their inputs with it, replacing the private per-adapter execute shapes.Nothing changes for existing callers.
throwOnErroromitted keepsexecutetyped asPromise<{ data }>and throwing.Also in here
throwOnErroris onToolClientOptionsin the generated-tools binding, soNeonToolsClientOptionscarries the flag.NeonToolsClientOptionsvalue intocreateNeonToolsnow takeOmit<NeonToolsClientOptions, "throwOnError">; spreading aboolean-typed flag would erase the literal narrowing the tests assert on.@neon/toolspatch.Verification
pnpm --filter @neon/tools exec vitest run --typecheckat 398f876: 12 files, 145 tests, type tests included, all green. Behaviors covered:throwOnError: falsereturns{ error }witherror instanceof NeonErrorandkind: "not_found"createNeonToolthrowOnError: falseonExecutesees the thrownNeonErrorand the caller still gets{ error }throwOnErrorstill rejects withNeonErrorfalsenarrows to the envelope, an annotatedCreateNeonToolsOptionstypes both outcomes, and enveloped tools passregisterNeonTools,toEveToolandtoMastraToolsThe suite runs against an injected
fetchreturning canned responses; no live API run.For your attention
NeonErroronly. Network faults from a customfetchand other exceptions still throw withthrowOnError: false, so a{ error }result always means a Neon API error.WithThrowModerewritesexecuteby inferring thePromise<{ data }>shape from the tool type; a tool whoseexecutedoes not match that shape passes through untouched.