-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: find server errors and display them with FileResponse errors #210
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ import { | |
FileResponse, | ||
MetadataApiDeployStatus, | ||
RequestStatus, | ||
DeployMessage, | ||
} from '@salesforce/source-deploy-retrieve'; | ||
import { ResultFormatter, ResultFormatterOptions, toArray } from './resultFormatter'; | ||
|
||
|
@@ -124,10 +125,23 @@ export class DeployResultFormatter extends ResultFormatter { | |
} | ||
|
||
protected displayFailures(): void { | ||
if (this.hasStatus(RequestStatus.Failed) && this.fileResponses?.length) { | ||
const failures = this.fileResponses.filter((f) => f.state === 'Failed'); | ||
this.sortFileResponses(failures); | ||
this.asRelativePaths(failures); | ||
if (this.hasStatus(RequestStatus.Failed)) { | ||
const failures: Array<FileResponse | DeployMessage> = []; | ||
|
||
if (this.fileResponses?.length) { | ||
const fileResponses = this.fileResponses.filter((f) => f.state === 'Failed'); | ||
this.sortFileResponses(fileResponses); | ||
this.asRelativePaths(fileResponses); | ||
failures.push(...fileResponses); | ||
} | ||
|
||
if (this.result?.response?.details?.componentFailures) { | ||
const deployMessages = toArray(this.result.response.details.componentFailures); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
deployMessages.map((deployMessage) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this could get really loopy on a big deployment fail (use of find within a loop where find is doing multiple string.includes) perf suggestion: iterate failures once to build a keyed Map< type+fullName>, deployMessage> At the very least, do the (do type and name match?) conditional first so that it mostly exits before having to do the string.includes ops |
||
// duplicate the problem message to the error property for displaying in the table | ||
failures.push(Object.assign(deployMessage, { error: deployMessage.problem })); | ||
}); | ||
} | ||
|
||
this.ux.log(''); | ||
this.ux.styledHeader(chalk.red(`Component Failures [${failures.length}]`)); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,7 @@ import * as sinon from 'sinon'; | |
import { expect } from 'chai'; | ||
import { Logger } from '@salesforce/core'; | ||
import { UX } from '@salesforce/command'; | ||
import { FileResponse } from '@salesforce/source-deploy-retrieve'; | ||
import { DeployMessage, FileResponse } from '@salesforce/source-deploy-retrieve'; | ||
import { stubInterface } from '@salesforce/ts-sinon'; | ||
import { getDeployResult } from '../commands/source/deployResponses'; | ||
import { DeployCommandResult, DeployResultFormatter } from '../../src/formatters/deployResultFormatter'; | ||
|
@@ -96,41 +96,50 @@ describe('DeployResultFormatter', () => { | |
expect(styledHeaderStub.calledOnce).to.equal(true); | ||
expect(logStub.calledTwice).to.equal(true); | ||
expect(tableStub.called).to.equal(true); | ||
expect(styledHeaderStub.firstCall.args[0]).to.contain('Component Failures [1]'); | ||
expect(styledHeaderStub.args[0][0]).to.include('Component Failures [2]'); | ||
const fileResponses = deployResultFailure.getFileResponses(); | ||
resolveExpectedPaths(fileResponses); | ||
expect(tableStub.firstCall.args[0]).to.deep.equal(fileResponses); | ||
const mutatedObject = Object.assign(deployResultFailure.response.details.componentFailures, { | ||
error: (deployResultFailure.response.details.componentFailures as DeployMessage).problem, | ||
}); | ||
|
||
const tableData = [...fileResponses, mutatedObject]; | ||
|
||
expect(tableStub.firstCall.args[0]).to.deep.equal(tableData); | ||
}); | ||
|
||
it('should output as expected for a test failure with verbose', async () => { | ||
const formatter = new DeployResultFormatter(logger, ux, { verbose: true }, deployResultTestFailure); | ||
formatter.display(); | ||
expect(styledHeaderStub.calledTwice).to.equal(true); | ||
expect(logStub.callCount).to.equal(5); | ||
expect(tableStub.calledTwice).to.equal(true); | ||
expect(styledHeaderStub.firstCall.args[0]).to.contain('Test Failures [1]'); | ||
expect(styledHeaderStub.secondCall.args[0]).to.contain('Apex Code Coverage'); | ||
expect(styledHeaderStub.calledThrice).to.equal(true); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these tests were giving false positives and needed to be updated |
||
expect(logStub.callCount).to.equal(7); | ||
expect(tableStub.calledThrice).to.equal(true); | ||
expect(styledHeaderStub.args[0][0]).to.include('Component Failures [1]'); | ||
expect(styledHeaderStub.args[1][0]).to.include('Test Failures [1]'); | ||
expect(styledHeaderStub.args[2][0]).to.include('Apex Code Coverage'); | ||
}); | ||
|
||
it('should output as expected for passing tests with verbose', async () => { | ||
const formatter = new DeployResultFormatter(logger, ux, { verbose: true }, deployResultTestSuccess); | ||
formatter.display(); | ||
expect(styledHeaderStub.calledTwice).to.equal(true); | ||
expect(logStub.callCount).to.equal(5); | ||
expect(tableStub.calledTwice).to.equal(true); | ||
expect(styledHeaderStub.firstCall.args[0]).to.contain('Test Success [1]'); | ||
expect(styledHeaderStub.secondCall.args[0]).to.contain('Apex Code Coverage'); | ||
expect(styledHeaderStub.calledThrice).to.equal(true); | ||
expect(logStub.callCount).to.equal(7); | ||
expect(tableStub.calledThrice).to.equal(true); | ||
expect(styledHeaderStub.args[0][0]).to.include('Component Failures [1]'); | ||
expect(styledHeaderStub.args[1][0]).to.include('Test Success [1]'); | ||
expect(styledHeaderStub.args[2][0]).to.include('Apex Code Coverage'); | ||
}); | ||
|
||
it('should output as expected for passing and failing tests with verbose', async () => { | ||
const formatter = new DeployResultFormatter(logger, ux, { verbose: true }, deployResultTestSuccessAndFailure); | ||
formatter.display(); | ||
expect(styledHeaderStub.callCount).to.equal(3); | ||
expect(logStub.callCount).to.equal(6); | ||
expect(tableStub.callCount).to.equal(3); | ||
expect(styledHeaderStub.firstCall.args[0]).to.contain('Test Failures [2]'); | ||
expect(styledHeaderStub.secondCall.args[0]).to.contain('Test Success [1]'); | ||
expect(styledHeaderStub.thirdCall.args[0]).to.contain('Apex Code Coverage'); | ||
expect(styledHeaderStub.callCount).to.equal(4); | ||
expect(logStub.callCount).to.equal(8); | ||
expect(tableStub.callCount).to.equal(4); | ||
expect(styledHeaderStub.args[0][0]).to.include('Component Failures [1]'); | ||
expect(styledHeaderStub.args[1][0]).to.include('Test Failures [2]'); | ||
expect(styledHeaderStub.args[2][0]).to.include('Test Success [1]'); | ||
expect(styledHeaderStub.args[3][0]).to.include('Apex Code Coverage'); | ||
}); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aren't componentFailures and fileResponses going to include some of the same errors, and so this would show duplicates?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ugh. dupes 🤦