Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 25 additions & 36 deletions src/commands/agent/validate/authoring-bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
import { Messages, SfError } from '@salesforce/core';
import { Messages } from '@salesforce/core';
import { MultiStageOutput } from '@oclif/multi-stage-output';
import { Agent } from '@salesforce/agents';
import { colorize } from '@oclif/core/ux';
Expand Down Expand Up @@ -88,44 +88,33 @@ export default class AgentValidateAuthoringBundle extends SfCommand<AgentValidat
],
});

try {
mso.skipTo('Validating Authoring Bundle');
const targetOrg = flags['target-org'];
const conn = targetOrg.getConnection(flags['api-version']);
const agent = await Agent.init({ connection: conn, project: this.project!, aabName });
const result = await agent.compile();
if (result.status === 'success') {
mso.updateData({ status: 'COMPLETED' });
mso.stop('completed');
return {
success: true,
};
} else {
throwAgentCompilationError(result.errors);
}
} catch (error) {
// Handle validation errors
const err = SfError.wrap(error);
let count = 0;
const rawError = err.message ? err.message : err.name;
const formattedError = rawError
.split('\n')
.map((line) => {
count += 1;
const type = line.split(':')[0];
const rest = line.includes(':') ? line.substring(line.indexOf(':')).trim() : '';
return `- ${colorize('red', type)}${rest}`;
})
.join('\n');
mso.skipTo('Validating Authoring Bundle');
const targetOrg = flags['target-org'];
const conn = targetOrg.getConnection(flags['api-version']);
const agent = await Agent.init({ connection: conn, project: this.project!, aabName });

mso.updateData({ errors: count.toString(), status: 'ERROR' });
mso.error();

this.error(messages.getMessage('error.compilationFailed', [formattedError]));
const result = await agent.compile();
if (result.status === 'success') {
mso.updateData({ status: 'COMPLETED' });
mso.stop('completed');
return {
success: false,
errors: err.message.split('\n'),
success: true,
};
}
// Validation failed with compilation errors -> exit 1 (404/500 set by @salesforce/agents)
mso.updateData({ errors: result.errors.length.toString(), status: 'ERROR' });
mso.error();

this.log(
messages.getMessage('error.compilationFailed', [
result.errors
.map(
(line) =>
`- ${colorize('red', line.errorType)}: ${line.description} [Ln ${line.lineStart}, Col ${line.colStart}]`
)
.join('\n'),
])
);
throwAgentCompilationError(result.errors);
}
}
9 changes: 7 additions & 2 deletions src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
*/
import { EOL } from 'node:os';
import { SfError } from '@salesforce/core';
import { CompilationError } from '@salesforce/agents';
import { CompilationError, COMPILATION_API_EXIT_CODES } from '@salesforce/agents';

/** Re-export so consumers can use the library's exit code contract (404 → 2, 500 → 3). */
export { COMPILATION_API_EXIT_CODES };

/**
* Utility function to generate SfError when there are agent compilation errors.
Expand All @@ -29,6 +32,7 @@ export function throwAgentCompilationError(compilationErrors: CompilationError[]
name: 'CompileAgentScriptError',
message: 'Unknown compilation error occurred',
data: compilationErrors,
exitCode: 1,
});
}

Expand All @@ -37,6 +41,7 @@ export function throwAgentCompilationError(compilationErrors: CompilationError[]
throw SfError.create({
name: 'CompileAgentScriptError',
message: errors.map((e) => `${e.errorType}: ${e.description} [Ln ${e.lineStart}, Col ${e.colStart}]`).join(EOL),
data: errors,
data: { errors },
exitCode: 1,
});
}
2 changes: 2 additions & 0 deletions test/commands/agent/validate/authoring-bundle.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ describe('Agent Validate Authoring Bundle', () => {
} catch (error) {
expect(error).to.be.instanceOf(SfError);
expect((error as SfError).name).to.equal('CompileAgentScriptError');
expect((error as SfError).exitCode).to.equal(1);
expect((error as SfError).message).to.include('SyntaxError: Invalid syntax [Ln 10, Col 5]');
expect((error as SfError).message).to.include('SyntaxError: Unknown error [Ln 15, Col 1]');
}
Expand All @@ -85,6 +86,7 @@ describe('Agent Validate Authoring Bundle', () => {
} catch (error) {
expect(error).to.be.instanceOf(SfError);
expect((error as SfError).name).to.equal('CompileAgentScriptError');
expect((error as SfError).exitCode).to.equal(1);
expect((error as SfError).message).to.equal('Unknown compilation error occurred');
}
});
Expand Down
3 changes: 1 addition & 2 deletions test/nuts/z1.agent.validate.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,9 @@ describe('agent validate authoring-bundle NUTs', function () {
// Retry up to 3 times total (1 initial + 2 retries) to handle transient failures
this.retries(2);

// Use the invalid authoring bundle (expects exit code 2 for compilation errors)
execCmd<AgentValidateAuthoringBundleResult>(
`agent validate authoring-bundle --api-name invalid --target-org ${getUsername()} --json`,
{ ensureExitCode: 2 }
{ ensureExitCode: 1 }
);
});
});
Loading