Skip to content

feat(errors): add top-level errors module for definitions and classification. - #1834

Merged
Hweinstock merged 8 commits into
aws:refactorfrom
Hweinstock:feat/common-errors
Jul 28, 2026
Merged

feat(errors): add top-level errors module for definitions and classification. #1834
Hweinstock merged 8 commits into
aws:refactorfrom
Hweinstock:feat/common-errors

Conversation

@Hweinstock

@Hweinstock Hweinstock commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Problem

See #1790

There is no consistent format for custom errors or way to override the exitCode.

Solution

Define a top level errors module that has exposes two pieces of functionality:

  • a base AgentCoreCLIError to build new errors from, that accepts metadata and "source" (used in telemetry).
  • a classify function that takes an arbitary value at the top-level and turns it into the correct error (with support for common AWS SDK exceptions).

Verification

  • Added unit tests at runnable for exitCode functionality, and for classify directly.
  • Tested e2e by adding failing api calls in the body and observing the logs.
{"level":"error","msg":"","time":1785158184077,"cliSessionId":"98973677-d14f-477b-9650-17e7a97bc88b","error":{"name":"AgentCoreCLIError","message":"User: {...}
 is not authorized to perform: bedrock-agentcore:GetAgentRuntime","stack":"AgentCoreCLIError: User: {...} is not authorized to perform: bedrock-agentcore:GetAg
entRuntime\n    at classify ({...}/agentcore-cli/src/errors/classify.tsx:16:16)\n    at <anonymous> ({...}/agentcore-cli/src/index.ts:70:21)\n    at async runWithExitCode
 ({...}/agentcore-cli/src/runnable/index.tsx:24:11)\n    at processTicksAndRejections (native:7:39)","exitCode":1,"meta":{"httpStatusCode":403,"requestId":"ffb5c1cf-379f-46a1-919d-a4c0f3f36aaa
","attempts":1,"totalRetryDelay":0},"source":"user"}}

Notes

this PR sets up the infrastructure, but there are more call sites to migrate. Migrating will come as a follow-up to keep the PR small and avoid churn with other open PRs.

@github-actions github-actions Bot added agentcore-harness-reviewing AgentCore Harness review in progress and removed agentcore-harness-reviewing AgentCore Harness review in progress labels Jul 27, 2026
@codecov-commenter

codecov-commenter commented Jul 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.91%. Comparing base (b57ed51) to head (ddc8536).

Additional details and impacted files
@@             Coverage Diff              @@
##           refactor    #1834      +/-   ##
============================================
+ Coverage     94.89%   94.91%   +0.02%     
============================================
  Files           151      154       +3     
  Lines          7421     7455      +34     
============================================
+ Hits           7042     7076      +34     
  Misses          379      379              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Hweinstock

Copy link
Copy Markdown
Contributor Author

audit fail is fixed in github.com//pull/1833

Comment thread src/index.ts Outdated
.child({ errorName: error.name, errorMessage: error.message, stack: error.stack ?? "" })
.error();
throw e;
const error = classify(e);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we classify here, instead of the top-level since we'll have the telemetry client in scope here, but not at the top-level.

@Hweinstock
Hweinstock marked this pull request as ready for review July 27, 2026 13:26
Comment thread src/errors/classify.tsx Outdated
if (ServiceException.isInstance(error)) {
const httpStatusCode = error.$metadata.httpStatusCode;
const source =
httpStatusCode !== undefined && httpStatusCode >= 400 && httpStatusCode < 500

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any chance something like 429: ThrottlingException shows up here? Just thinking about 400s that might not truly be user errors.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah good question. If the CLI sees a throttling exception its difficult to know if its an issue on the CLI making too many requests, or a user spamming through the CLI.

We don't want any internal faults to be user-trigger-able, so I believe its safer to make this a user error and maintain the error name in telemetry. That way if we see a bunch of throttling across the board, we know there is likely a bug on the CLI.

Comment thread src/errors/errors.tsx Outdated
nborges-aws
nborges-aws previously approved these changes Jul 27, 2026

@AlexanderRichey AlexanderRichey left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! One thing I think would be a bit nicer would be not to have classify but to have an alternative constructor for this case that would do the same thing:

const error = AgentCoreCLIError.fromError(e)

This would keep all of the public error handling code neatly exposed through one class.

Second thing is getting rid of UNKNOWN as an error type in favor of INTERNAL.

Comment thread src/index.ts Outdated
.child({ errorName: error.name, errorMessage: error.message, stack: error.stack ?? "" })
.error();
throw e;
const error = classify(e);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if an alternative constructor would be more elegant here. Something like this?

const error = AgentCoreCLIError.fromError(e)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it! I'll swap it over.

Comment thread src/errors/types.tsx Outdated
INTERNAL: "internal",
USER: "user",
SERVICE: "service",
UNKNOWN: "unknown",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we get rid of UNKNOWN? It doesn't seem meaningfully different from INTERNAL, unless I'm missing something.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

discussed offline. distinction doesn't justify a separate field, aligning on INTERNAL.

@Hweinstock
Hweinstock force-pushed the feat/common-errors branch from a01d565 to ddc8536 Compare July 27, 2026 20:59
@Hweinstock
Hweinstock merged commit 0a43f48 into aws:refactor Jul 28, 2026
8 checks passed
@Hweinstock
Hweinstock deleted the feat/common-errors branch July 28, 2026 13:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants