fix(core): prioritize detailed error messages for code assist setup (#17852)

This commit is contained in:
Gaurav
2026-02-02 20:27:55 -08:00
committed by GitHub
parent 5b254c379c
commit 1b274b081d
3 changed files with 50 additions and 8 deletions

View File

@@ -305,6 +305,9 @@ describe('clipboardUtils', () => {
});
it('should return null if tool is not yet detected', async () => {
// Unset session type to ensure no tool is detected automatically
delete process.env['XDG_SESSION_TYPE'];
// Don't prime the tool
const result = await clipboardUtils.saveClipboardImage(mockTargetDir);
expect(result).toBe(null);

View File

@@ -312,6 +312,32 @@ describe('setupUser for new user', () => {
userTierName: 'paid',
});
});
it('should throw ineligible tier error when onboarding fails and ineligible tiers exist', async () => {
vi.stubEnv('GOOGLE_CLOUD_PROJECT', '');
mockLoad.mockResolvedValue({
allowedTiers: [mockPaidTier],
ineligibleTiers: [
{
reasonCode: 'UNSUPPORTED_LOCATION',
reasonMessage:
'Your current account is not eligible for Gemini Code Assist for individuals because it is not currently available in your location.',
tierId: 'free-tier',
tierName: 'Gemini Code Assist for individuals',
},
],
});
mockOnboardUser.mockResolvedValue({
done: true,
response: {
cloudaicompanionProject: {},
},
});
await expect(setupUser({} as OAuth2Client)).rejects.toThrow(
'Your current account is not eligible for Gemini Code Assist for individuals because it is not currently available in your location.',
);
});
});
describe('setupUser validation', () => {

View File

@@ -7,6 +7,7 @@
import type {
ClientMetadata,
GeminiUserTier,
IneligibleTier,
LoadCodeAssistResponse,
OnboardUserRequest,
} from './types.js';
@@ -35,6 +36,16 @@ export class ValidationCancelledError extends Error {
}
}
export class IneligibleTierError extends Error {
readonly ineligibleTiers: IneligibleTier[];
constructor(ineligibleTiers: IneligibleTier[]) {
const reasons = ineligibleTiers.map((t) => t.reasonMessage).join(', ');
super(reasons);
this.ineligibleTiers = ineligibleTiers;
}
}
export interface UserData {
projectId: string;
userTier: UserTierId;
@@ -127,13 +138,7 @@ export async function setupUser(
}
// If user is not setup for standard tier, inform them about all other tiers they are ineligible for.
if (loadRes.ineligibleTiers && loadRes.ineligibleTiers.length > 0) {
const reasons = loadRes.ineligibleTiers
.map((t) => t.reasonMessage)
.join(', ');
throw new Error(reasons);
}
throw new ProjectIdRequiredError();
throwIneligibleOrProjectIdError(loadRes);
}
return {
projectId: loadRes.cloudaicompanionProject,
@@ -180,7 +185,8 @@ export async function setupUser(
userTierName: tier.name,
};
}
throw new ProjectIdRequiredError();
throwIneligibleOrProjectIdError(loadRes);
}
return {
@@ -190,6 +196,13 @@ export async function setupUser(
};
}
function throwIneligibleOrProjectIdError(res: LoadCodeAssistResponse): never {
if (res.ineligibleTiers && res.ineligibleTiers.length > 0) {
throw new IneligibleTierError(res.ineligibleTiers);
}
throw new ProjectIdRequiredError();
}
function getOnboardTier(res: LoadCodeAssistResponse): GeminiUserTier {
for (const tier of res.allowedTiers || []) {
if (tier.isDefault) {