Skip to content

Commit 0bdc677

Browse files
authored
fix: emit ValidationError instead of UnknownError in create telemetry (#1342)
* fix: emit ValidationError instead of UnknownError in create telemetry * fix: emit ValidationError in add.* command validation failures
1 parent 34886be commit 0bdc677

9 files changed

Lines changed: 32 additions & 9 deletions

esbuild.config.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ await esbuild.build({
4848
platform: 'node',
4949
format: 'esm',
5050
minify: true,
51+
keepNames: true,
5152
jsx: 'automatic',
5253
// Inject require shim for ESM compatibility with CommonJS dependencies
5354
banner: {

integ-tests/add-remove-resources.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,23 @@ describe('integration: add and remove resources', () => {
197197
});
198198
});
199199

200+
describe('add validation failure telemetry', () => {
201+
it('emits ValidationError for add memory with missing --name', async () => {
202+
telemetry.clearEntries();
203+
const result = await runCLI(['add', 'memory', '--strategies', 'SEMANTIC', '--json'], project.projectPath, {
204+
env: telemetry.env,
205+
});
206+
207+
expect(result.exitCode).toBe(1);
208+
telemetry.assertMetricEmitted({
209+
command: 'add.memory',
210+
exit_reason: 'failure',
211+
error_name: 'ValidationError',
212+
error_source: 'user',
213+
});
214+
});
215+
});
216+
200217
describe('remove all', () => {
201218
it('resets all schemas and emits telemetry', async () => {
202219
const result = await runCLI(['remove', 'all', '--yes', '--json'], project.projectPath, {

integ-tests/create-edge-cases.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ describe.skipIf(!prereqs.npm || !prereqs.git)('integration: create edge cases',
3838
telemetry.assertMetricEmitted({
3939
command: 'create',
4040
exit_reason: 'failure',
41+
error_name: 'ValidationError',
42+
error_source: 'user',
4143
agent_language: 'python',
4244
has_agent: 'true',
4345
});

src/cli/commands/create/command.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { getWorkingDirectory, serializeResult } from '../../../lib';
1+
import { ValidationError, getWorkingDirectory, serializeResult } from '../../../lib';
22
import type {
33
BuildType,
44
ModelProvider,
@@ -132,7 +132,7 @@ async function handleCreateCLI(options: CreateOptions): Promise<void> {
132132
async () => {
133133
const validation = validateCreateOptions(options, cwd);
134134
if (!validation.valid) {
135-
throw new Error(validation.error);
135+
throw new ValidationError(validation.error!);
136136
}
137137
const green = '\x1b[32m';
138138
const reset = '\x1b[0m';

src/cli/primitives/AgentPrimitive.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
ConflictError,
55
NoProjectError,
66
ResourceNotFoundError,
7+
ValidationError,
78
findConfigRoot,
89
serializeResult,
910
setEnvVar,
@@ -301,7 +302,7 @@ export class AgentPrimitive extends BasePrimitive<AddAgentOptions, RemovableReso
301302
await runCliCommand('add.agent', !!cliOptions.json, async () => {
302303
const validation = validateAddAgentOptions(cliOptions);
303304
if (!validation.valid) {
304-
throw new Error(validation.error);
305+
throw new ValidationError(validation.error!);
305306
}
306307

307308
// Parse custom claims JSON if provided (already validated by validateAddAgentOptions)

src/cli/primitives/CredentialPrimitive.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
ConflictError,
33
ResourceNotFoundError,
4+
ValidationError,
45
findConfigRoot,
56
getEnvVar,
67
serializeResult,
@@ -315,7 +316,7 @@ export class CredentialPrimitive extends BasePrimitive<AddCredentialOptions, Rem
315316
});
316317

317318
if (!validation.valid) {
318-
throw new Error(validation.error);
319+
throw new ValidationError(validation.error!);
319320
}
320321

321322
const addOptions =

src/cli/primitives/GatewayPrimitive.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ResourceNotFoundError, findConfigRoot, serializeResult, toError } from '../../lib';
1+
import { ResourceNotFoundError, ValidationError, findConfigRoot, serializeResult, toError } from '../../lib';
22
import type { Result } from '../../lib/result';
33
import type {
44
AgentCoreGateway,
@@ -191,7 +191,7 @@ export class GatewayPrimitive extends BasePrimitive<AddGatewayOptions, Removable
191191
await runCliCommand('add.gateway', !!cliOptions.json, async () => {
192192
const validation = validateAddGatewayOptions(cliOptions);
193193
if (!validation.valid) {
194-
throw new Error(validation.error);
194+
throw new ValidationError(validation.error!);
195195
}
196196

197197
// Parse custom claims JSON if provided (already validated)

src/cli/primitives/GatewayTargetPrimitive.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
APP_DIR,
33
MCP_APP_SUBDIR,
44
ResourceNotFoundError,
5+
ValidationError,
56
findConfigRoot,
67
requireConfigRoot,
78
serializeResult,
@@ -323,7 +324,7 @@ export class GatewayTargetPrimitive extends BasePrimitive<AddGatewayTargetOption
323324
await runCliCommand('add.gateway-target', !!cliOptions.json, async () => {
324325
const validation = await validateAddGatewayTargetOptions(cliOptions);
325326
if (!validation.valid) {
326-
throw new Error(validation.error);
327+
throw new ValidationError(validation.error!);
327328
}
328329

329330
// Map CLI flag values to internal types

src/cli/primitives/MemoryPrimitive.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ResourceNotFoundError, findConfigRoot, serializeResult, toError } from '../../lib';
1+
import { ResourceNotFoundError, ValidationError, findConfigRoot, serializeResult, toError } from '../../lib';
22
import type { Result } from '../../lib/result';
33
import type {
44
Memory,
@@ -204,7 +204,7 @@ export class MemoryPrimitive extends BasePrimitive<AddMemoryOptions, RemovableMe
204204
});
205205

206206
if (!validation.valid) {
207-
throw new Error(validation.error);
207+
throw new ValidationError(validation.error!);
208208
}
209209

210210
const result = await this.add({

0 commit comments

Comments
 (0)