fix(cli): surface real cause when discoverAzureBot fails#2833
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Improves Azure bot discovery error reporting in the Teams CLI so discoverAzureBot() only returns null for the true “not found” case, and otherwise surfaces actionable Azure CLI failures (auth/network/permissions/etc.) to callers (esp. --json automation), while keeping app doctor resilient.
Changes:
- Update
discoverAzureBot()to rethrow non-empty-results failures asCliError('API_ARM_ERROR', ...)and preferstderrfor the message. - Make
app doctorrecord a single failing check when discovery throws, rather than continuing with misleading “not found” output. - Add unit tests covering
nullvs thrown-error behavior and message preservation.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| packages/cli/src/apps/bot-handler.ts | Stop swallowing az failures; throw CliError('API_ARM_ERROR') with stderr-first diagnostic text. |
| packages/cli/src/commands/app/doctor.ts | Catch discovery errors and report them as a dedicated fail entry; avoid “Azure bot not found” when discovery failed. |
| packages/cli/tests/discover-azure-bot.test.ts | Add tests validating null-on-empty-results and thrown-error behavior for discoverAzureBot(). |
heyitsaamir
reviewed
May 12, 2026
Collaborator
Author
discoverAzureBot's helper catches and outer catch collapsed every az
failure into null, indistinguishable from a legitimate "bot not found"
result and causing --yes/--json callers to report a misleading
NOT_FOUND_AZURE_BOT code.
Removes the bug-shaped catches in findBotByName and the outer catch of
findBotByMsaAppIdViaList so az errors propagate. Keeps the
findBotByMsaAppIdViaGraph catch (intentional fallback to list when the
resource-graph extension is unavailable) and the per-bot inner catch
inside the list scan (per-element resilience). The outer catch in
discoverAzureBot now rewraps as CliError('API_ARM_ERROR') with the
original stderr/message preserved. Doctor wraps the call so a thrown
error becomes one fail entry instead of terminating the report.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
c2e32d0 to
4e92688
Compare
heyitsaamir
approved these changes
May 13, 2026
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.


Fixes #2830.
discoverAzureBotand its helpers collapsed every az failure intonull, indistinguishable from a real "bot not found."app update --jsonthen returned a misleadingNOT_FOUND_AZURE_BOT; under--yes, an agent could try to recreate a bot that already exists but couldn't be read.Rebased on top of #2825's fallback chain. Only the bug-shaped catches are removed; the two structural ones are kept:
findBotByNameouter catch — removed (pure suppression).findBotByMsaAppIdViaListouter catch — removed (pure suppression).findBotByMsaAppIdViaListper-bot catch — kept (per-element resilience insidePromise.all).findBotByMsaAppIdViaGraphouter catch — kept (intentional fallback signal: routes "graph extension unavailable" to the list path; pinned by fix(cli): doctor finds Azure bot when resource name != botId #2825's tests).discoverAzureBotrewraps the surviving catch asCliError('API_ARM_ERROR', 'Failed to discover Azure bot: <stderr>')— preferringerror.stderrovererror.messageso the real az diagnostic surfaces instead ofCommand failed: cmd /c az.cmd ....app doctorwraps the call so a throw becomes afailentry instead of terminating the report.🤖 Generated with Claude Code