Skip to content

Commit dd36361

Browse files
committed
fix: extract handler transform for ut, handle undefined
1 parent 98d4550 commit dd36361

File tree

3 files changed

+75
-25
lines changed

3 files changed

+75
-25
lines changed

src/errorHandling.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import { SfError } from '@salesforce/core';
99
import { OclifError } from '@oclif/core/lib/interfaces/errors.js';
1010
import { SfCommandError } from './types.js';
11+
import { removeEmpty } from './util.js';
1112

1213
/**
1314
*
@@ -65,6 +66,28 @@ export const errorIsTypeError = (error: Error | SfError): boolean =>
6566
Boolean(error.stack?.includes('TypeError')) ||
6667
('cause' in error && error.cause instanceof Error && errorIsTypeError(error.cause));
6768

69+
export const errorToSfCommandError = (
70+
codeFromError: number,
71+
error: Error | SfError | SfCommandError,
72+
commandName: string
73+
): SfCommandError => ({
74+
...removeEmpty({
75+
code: codeFromError,
76+
actions: 'actions' in error ? error.actions : null,
77+
context: ('context' in error ? error.context : commandName) ?? commandName,
78+
commandName: ('commandName' in error ? error.commandName : commandName) ?? commandName,
79+
data: 'data' in error ? error.data : null,
80+
result: 'result' in error ? error.result : null,
81+
}),
82+
...{
83+
message: error.message,
84+
name: error.name ?? 'Error',
85+
status: codeFromError,
86+
stack: error.stack,
87+
exitCode: codeFromError,
88+
},
89+
});
90+
6891
/** custom typeGuard for handling the fact the SfCommand doesn't know about oclif error structure */
6992
const isOclifError = <T extends Error | SfError | SfCommandError>(e: T): e is T & OclifError =>
7093
'oclif' in e ? true : false;

src/sfCommand.ts

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ import { SfCommandError } from './types.js';
2424
import { formatActions, formatError } from './errorFormatting.js';
2525
import { StandardColors } from './ux/standardColors.js';
2626
import { confirm, secretPrompt, PromptInputs } from './ux/prompts.js';
27-
import { removeEmpty } from './util.js';
28-
import { computeErrorCode } from './errorHandling.js';
27+
import { computeErrorCode, errorToSfCommandError } from './errorHandling.js';
2928

3029
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
3130
const messages = Messages.loadMessages('@salesforce/sf-plugins-core', 'messages');
@@ -34,7 +33,7 @@ export type SfCommandInterface = {
3433
configurationVariablesSection?: HelpSection;
3534
envVariablesSection?: HelpSection;
3635
errorCodes?: HelpSection;
37-
} & Command.Class
36+
} & Command.Class;
3837

3938
/**
4039
* A base command that provided common functionality for all sf commands.
@@ -391,26 +390,7 @@ export abstract class SfCommand<T> extends Command {
391390
const codeFromError = computeErrorCode(error);
392391
process.exitCode = codeFromError;
393392

394-
const sfErrorProperties = removeEmpty({
395-
code: codeFromError,
396-
actions: 'actions' in error ? error.actions : null,
397-
context: 'context' in error ? error.context : this.statics.name,
398-
commandName: 'commandName' in error ? error.commandName : this.statics.name,
399-
data: 'data' in error ? error.data : null,
400-
result: 'result' in error ? error.result : null,
401-
});
402-
403-
// Create printable error object
404-
const sfCommandError: SfCommand.Error = {
405-
...sfErrorProperties,
406-
...{
407-
message: error.message,
408-
name: error.name ?? 'Error',
409-
status: process.exitCode,
410-
stack: error.stack,
411-
exitCode: process.exitCode,
412-
},
413-
};
393+
const sfCommandError = errorToSfCommandError(codeFromError, error, this.statics.name);
414394

415395
if (this.jsonEnabled()) {
416396
this.logJson(this.toErrorJson(sfCommandError));
@@ -469,6 +449,6 @@ export namespace SfCommand {
469449
status: number;
470450
result: T;
471451
warnings?: Warning[];
472-
}
452+
};
473453
export type Error = SfCommandError;
474454
}

test/unit/errorHandling.test.ts

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*/
77
import { expect } from 'chai';
88
import { SfError } from '@salesforce/core';
9-
import { computeErrorCode, errorIsGack, errorIsTypeError } from '../../src/errorHandling.js';
9+
import { computeErrorCode, errorIsGack, errorIsTypeError, errorToSfCommandError } from '../../src/errorHandling.js';
1010

1111
describe('typeErrors', () => {
1212
let typeError: Error;
@@ -122,3 +122,50 @@ describe('precedence', () => {
122122
expect(computeErrorCode(e)).to.equal(10);
123123
});
124124
});
125+
126+
describe('errorToSfCommandError', () => {
127+
it('basic', () => {
128+
const result = errorToSfCommandError(1, new Error('foo'), 'the:cmd');
129+
expect(result).to.deep.include({
130+
code: 1,
131+
status: 1,
132+
exitCode: 1,
133+
commandName: 'the:cmd',
134+
context: 'the:cmd',
135+
message: 'foo',
136+
name: 'Error', // this is the default
137+
});
138+
expect(result.stack).to.be.a('string').and.include('Error: foo');
139+
});
140+
describe('context', () => {
141+
it('sfError with context', () => {
142+
const sfError = SfError.create({ name: 'myError', message: 'foo', actions: ['bar'], context: 'myContext' });
143+
const result = errorToSfCommandError(8, sfError, 'the:cmd');
144+
expect(result).to.deep.include({
145+
code: 8,
146+
status: 8,
147+
exitCode: 8,
148+
commandName: 'the:cmd',
149+
context: 'myContext',
150+
message: 'foo',
151+
name: 'myError',
152+
});
153+
expect(result.stack).to.be.a('string').and.include('myError: foo');
154+
});
155+
it('sfError with undefined context', () => {
156+
const sfError = SfError.create({ name: 'myError', message: 'foo', actions: ['bar'], context: undefined });
157+
const result = errorToSfCommandError(8, sfError, 'the:cmd');
158+
expect(result).to.deep.include({
159+
code: 8,
160+
status: 8,
161+
exitCode: 8,
162+
commandName: 'the:cmd',
163+
// defaults to the command name
164+
context: 'the:cmd',
165+
message: 'foo',
166+
name: 'myError',
167+
});
168+
expect(result.stack).to.be.a('string').and.include('myError: foo');
169+
});
170+
});
171+
});

0 commit comments

Comments
 (0)