Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickjuchli committed Aug 28, 2019
1 parent 51d28ba commit fca1005
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 9 deletions.
15 changes: 9 additions & 6 deletions src/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -416,25 +416,28 @@ export class Client {
*/
async list(path = ""): Promise<FileInfo[]> {
const validPath = await this.protectWhitespace(path)
let lastError: any
for (const candidate of this._availableListCommands) {
const command = `${candidate} ${validPath}`.trim()
await this.prepareTransfer(this)
try {
const parsedList = await this._requestListWithCommand(command)
// The successful candidate will from now on be the only command
// used in all subsequent list requests.
// Use successful candidate for all subsequent requests.
this._availableListCommands = [ candidate ]
return parsedList
}
catch (err) {
const hasOnlyOneCandidate = this._availableListCommands.length === 1
const shouldTryAnotherCandidate = err instanceof FTPError && err.code >= 500
if (hasOnlyOneCandidate || !shouldTryAnotherCandidate) {
const maybeSyntaxError = err instanceof FTPError && err.code >= 500
if (!maybeSyntaxError) {
throw err
}
lastError = err
}
}
throw new Error(`Can't get directory listing, tried: ${this._availableListCommands.join(", ")}`)
// Always rethrow an exception of the last candidate. That way this method
// behaves the same regardless whether it just evaluated several list commands
// or just used the single one selected as compatible in an earlier request.
throw lastError
}

/**
Expand Down
8 changes: 5 additions & 3 deletions test/downloadSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,12 +201,14 @@ describe("Download directory listing", function() {
return client.list();
})

it("throws error when all available list commands fail", function() {
it("throws error of last candidate when all available list commands fail", function() {
let counter = 1
client.ftp.socket.on("didSend", () => {
client.ftp.socket.emit("data", "501 Syntax error")
client.ftp.socket.emit("data", "501 Syntax error " + counter)
counter++
});
return client.list().catch(err => {
assert.equal(err.message, "Can't get directory listing, tried: LIST -a, LIST")
assert.equal(err.message, "501 Syntax error 2")
});
})

Expand Down

0 comments on commit fca1005

Please sign in to comment.