Skip to content

Commit eb5b447

Browse files
betegonclaude
andcommitted
fix(errors): use ResolutionError for org-not-found in buildOrgFailureError
ContextError means the user omitted a required value ("Organization is required."), but buildOrgFailureError is reached when the org slug was provided and returned a 404. Switch to ResolutionError so the message reads "Organization 'my-org' not found." which matches the actual scenario. Also drops the leaked internal detail about listTeams status. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 8801c8e commit eb5b447

File tree

2 files changed

+14
-14
lines changed

2 files changed

+14
-14
lines changed

src/lib/resolve-team.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import type { SentryTeam } from "../types/index.js";
99
import { listOrganizations, listTeams } from "./api-client.js";
10-
import { ApiError, CliError, ContextError } from "./errors.js";
10+
import { ApiError, CliError, ContextError, ResolutionError } from "./errors.js";
1111
import { getSentryBaseUrl } from "./sentry-urls.js";
1212

1313
/**
@@ -55,6 +55,7 @@ export type ResolveTeamOptions = {
5555
* @param options - Resolution options (team flag, usage hint, detection source)
5656
* @returns Team slug to use
5757
* @throws {ContextError} When team cannot be resolved
58+
* @throws {ResolutionError} When org slug returns 404
5859
*/
5960
export async function resolveTeam(
6061
orgSlug: string,
@@ -117,26 +118,25 @@ export async function resolveTeam(
117118
*/
118119
async function buildOrgFailureError(
119120
orgSlug: string,
120-
error: ApiError,
121+
_error: ApiError,
121122
options: ResolveTeamOptions
122123
): Promise<never> {
123124
const orgHint = await fetchOrgListHint(
124125
`Specify org explicitly: ${options.usageHint}`
125126
);
126127

127-
const alternatives = [
128-
`Could not list teams for org '${orgSlug}' (${error.status})`,
129-
];
128+
const suggestions: string[] = [];
130129
if (options.detectedFrom) {
131-
alternatives.push(
130+
suggestions.push(
132131
`Org '${orgSlug}' was auto-detected from ${options.detectedFrom}`
133132
);
134133
}
135-
alternatives.push(orgHint);
134+
suggestions.push(orgHint);
136135

137-
throw new ContextError(
138-
"Organization",
136+
throw new ResolutionError(
137+
`Organization '${orgSlug}'`,
138+
"not found",
139139
`${options.usageHint} --team <team-slug>`,
140-
alternatives
140+
suggestions
141141
);
142142
}

test/commands/project/create.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
import { createCommand } from "../../../src/commands/project/create.js";
1919
// biome-ignore lint/performance/noNamespaceImport: needed for spyOn mocking
2020
import * as apiClient from "../../../src/lib/api-client.js";
21-
import { ApiError, CliError, ContextError } from "../../../src/lib/errors.js";
21+
import { ApiError, CliError, ContextError, ResolutionError } from "../../../src/lib/errors.js";
2222
// biome-ignore lint/performance/noNamespaceImport: needed for spyOn mocking
2323
import * as resolveTarget from "../../../src/lib/resolve-target.js";
2424
import type { SentryProject, SentryTeam } from "../../../src/types/index.js";
@@ -505,9 +505,9 @@ describe("project create", () => {
505505
const err = await func
506506
.call(context, { json: false }, "my-app", "node")
507507
.catch((e: Error) => e);
508-
expect(err).toBeInstanceOf(ContextError);
508+
expect(err).toBeInstanceOf(ResolutionError);
509509
expect(err.message).toContain("acme-corp");
510-
expect(err.message).toContain("404");
510+
expect(err.message).toContain("not found");
511511
// Should show the user's actual orgs to help them pick the right one
512512
expect(err.message).toContain("Your organizations");
513513
expect(err.message).toContain("other-org");
@@ -528,7 +528,7 @@ describe("project create", () => {
528528
const err = await func
529529
.call(context, { json: false }, "my-app", "node")
530530
.catch((e: Error) => e);
531-
expect(err).toBeInstanceOf(ContextError);
531+
expect(err).toBeInstanceOf(ResolutionError);
532532
expect(err.message).toContain("auto-detected from test/mocks/routes.ts");
533533
expect(err.message).toContain("123");
534534
expect(err.message).toContain("Your organizations");

0 commit comments

Comments
 (0)