Skip to content
Merged
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
8 changes: 4 additions & 4 deletions packages/code-analyzer-apexguru-engine/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export type ApexGuruEngineConfig = {

/**
* Maximum time to wait for ApexGuru API response (in milliseconds)
* Default: 300000 (5 minutes)
* Default: 600000 (10 minutes)
*/
api_timeout_ms: number;

Expand Down Expand Up @@ -42,7 +42,7 @@ export type ApexGuruEngineConfig = {
* Default configuration values
*/
export const DEFAULT_APEXGURU_ENGINE_CONFIG: ApexGuruEngineConfig = {
api_timeout_ms: 300000, // 5 minutes
api_timeout_ms: 600000, // 10 minutes
api_initial_retry_ms: 2000, // 2 seconds
api_max_retry_ms: 60000, // 60 seconds
api_backoff_multiplier: 2 // 2x exponential backoff
Expand All @@ -60,9 +60,9 @@ export const APEXGURU_ENGINE_CONFIG_DESCRIPTION: ConfigDescription = {
defaultValue: null
},
api_timeout_ms: {
descriptionText: 'Maximum time to wait for ApexGuru API response (in milliseconds). Default: 300000 (5 minutes)',
descriptionText: 'Maximum time to wait for ApexGuru API response (in milliseconds). Default: 600000 (10 minutes)',
valueType: 'number',
defaultValue: 300000
defaultValue: 600000
},
api_initial_retry_ms: {
descriptionText: 'Initial retry delay for polling ApexGuru API (in milliseconds). Default: 2000 (2 seconds)',
Expand Down
13 changes: 11 additions & 2 deletions packages/code-analyzer-apexguru-engine/src/engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export class ApexGuruEngine extends EngineEventEmitter implements Engine {
this.apexGuruService.cleanup();
if (this.isInvalidSessionError(error)) {
return this.skipWithError('INVALID_SESSION',
'ApexGuru skipped the scan because your org session is invalid or expired. (401 Unauthorized: invalid session).\n' +
'Code Analyzer skipped ApexGuru scan because your org session is invalid or expired. (401 Unauthorized: invalid session).\n' +
'Re-authenticate: sf org login web\n' +
'Then run the scan again.',
'');
Expand Down Expand Up @@ -204,7 +204,8 @@ export class ApexGuruEngine extends EngineEventEmitter implements Engine {
const detail = error instanceof Error ? error.message : String(error);
if (this.isScanTimeoutError(error)) {
return this.skipWithError('SCAN_TIMEOUT',
`Code Analyzer skipped ApexGuru scan because the workspace scan timed out after ${this.config.api_timeout_ms} ms.`,
`Code Analyzer skipped ApexGuru scan because the workspace scan timed out after ${formatSeconds(this.config.api_timeout_ms)}. ` +
'Increase the timeout setting in the Code Analyzer configuration file.',
'');
}
if (this.isApiUnavailableError(error)) {
Expand Down Expand Up @@ -288,6 +289,14 @@ export class ApexGuruEngine extends EngineEventEmitter implements Engine {
}
}


function formatSeconds(ms: number): string {
const seconds = ms / 1000;
// Drop the trailing ".0" for whole numbers, keep up to 1 decimal otherwise.
const rounded = Number.isInteger(seconds) ? seconds : Math.round(seconds * 10) / 10;
return `${rounded} ${rounded === 1 ? 'second' : 'seconds'}`;
}

/**
* Convert ApexGuru violation to Code Analyzer violation format
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,9 @@ export class ApexGuruAuthService {
const errorMessage = err instanceof Error ? err.message : String(err);
this.emitLogEvent(LogLevel.Fine, `Failed to authenticate with org '${config.targetOrg}': ${errorMessage}`);
throw new Error(
`Failed to authenticate with org '${config.targetOrg}'. ` +
'Please verify the org alias/username and ensure you are authenticated:\n' +
' sf org list\n' +
' sf org login web'
`We couldn't find the org '${config.targetOrg}', or it isn't authenticated.\n\n` +
`Run sf org list to see available orgs.\n` +
`Run sf org login web --alias ${config.targetOrg} to authenticate a new org.`
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -360,8 +360,8 @@ function formatHttpError(status: number, body: string): string {
const statusText = STATUS_TEXT[status] ?? 'Error';
const detail = summarizeErrorBody(body);
return detail
? `SFAP API returned ${status} ${statusText}: ${detail}`
: `SFAP API returned ${status} ${statusText}`;
? `${status} ${statusText}: ${detail}`
: `${status} ${statusText}`;
}

const STATUS_TEXT: Record<number, string> = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ describe('ApexGuruAuthService', () => {

await expect(authService.initialize({ targetOrg: 'invalid-org' }))
.rejects
.toThrow("Failed to authenticate with org 'invalid-org'");
.toThrow("We couldn't find the org 'invalid-org', or it isn't authenticated.");
});

it('should initialize with default org when no targetOrg provided', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ describe('ApexGuruEngine', () => {
status: 'skipped',
error: {
code: 'INVALID_SESSION',
message: 'ApexGuru skipped the scan because your org session is invalid or expired. (401 Unauthorized: invalid session).\n' +
message: 'Code Analyzer skipped ApexGuru scan because your org session is invalid or expired. (401 Unauthorized: invalid session).\n' +
'Re-authenticate: sf org login web\n' +
'Then run the scan again.',
remediation: ''
Expand Down Expand Up @@ -299,11 +299,12 @@ describe('ApexGuruEngine', () => {
status: 'skipped',
error: {
code: 'SCAN_TIMEOUT',
message: 'Code Analyzer skipped ApexGuru scan because the workspace scan timed out after 300000 ms.',
message: 'Code Analyzer skipped ApexGuru scan because the workspace scan timed out after 600 seconds. ' +
'Increase the timeout setting in the Code Analyzer configuration file.',
remediation: ''
}
});
expect(logSpy).toHaveBeenCalledWith(LogLevel.Warn, expect.stringContaining('workspace scan timed out after 300000 ms'));
expect(logSpy).toHaveBeenCalledWith(LogLevel.Warn, expect.stringContaining('workspace scan timed out after 600 seconds'));
expect(mockApexGuruService.cleanup).toHaveBeenCalled();
});

Expand Down
Loading