Open zacronos opened 7 years ago
@ozankaya
The exception originates in the underlying ssh2-streams library. The fact that it is coming through in the wrong place is a consequence of an unfortunate decision I made regarding how to handle waiting for commands to complete under the hood -- that part needs to be redesigned. Thanks for the bug report.
@zacronos any workaround?
@lfreneda I would suggest using .list()
to verify a file / directory's presence. And if the file/directory isn't there, do whatever makes sense (aborting for a file download, creating the directory for a file upload, etc).
It's a bit inconvenient because you'd need to do it for each path segment, but it should work.
Hello
We encountered this error. We have developed a fix. In the "put" function, instead of:
this.put = function(input, destPath) {
return Promise["try"](function() {
var options;
if (restartOffset !== null) {
options = {
start: restartOffset,
flags: 'r+'
};
restartOffset = null;
}
if (typeof input === 'string') {
if (!options) {
return promisifiedClientMethods.fastPut(input, destPath);
}
input = fs.createReadStream(input);
}
return promisifiedClientMethods.createWriteStream(destPath, options).then(function(stream) {
finishLogic(stream);
if (input instanceof Buffer) {
return stream.end(input);
}
input.pipe(stream);
return void 0;
});
Just have to code:
this.put = function(input, destPath) {
return Promise["try"](function() {
var options;
if (restartOffset !== null) {
options = {
start: restartOffset,
flags: 'r+'
};
restartOffset = null;
}
if (typeof input === 'string') {
if (!options) {
return promisifiedClientMethods.fastPut(input, destPath);
}
input = fs.createReadStream(input);
}
return promisifiedClientMethods.createWriteStream(destPath, options).then(function(stream) {
return new Promise((resolve, reject) => {
stream.on('error', (err) => {
console.log('write stream error ' + err);
reject(err);
});
stream.on('end', () => {
resolve();
});
finishLogic(stream);
if (input instanceof Buffer) {
stream.end(input);
resolve();
return;
}
input.pipe(stream);
});
});
The problem was that the "put" function does not handle the errors of the write stream. I don't know well about bluebird promises but there was no stream.on('error', ...)
. That is why, when the folder does not exist, the thread was killed.
With this solution, "put" function rejects the write stream errors and resolve when the write stream ends.
About your "list directory" workaround. This is not a solution for us since some FTP servers allow put actions but not list directories.
Would it be possible to integrate this fix please? I am not familiar to coffee script...
A little update, here is the code we actually use:
this.put = function(input, destPath) {
return new Promise((resolve, reject) => {
var options;
if (restartOffset !== null) {
options = {
start: restartOffset,
flags: 'r+'
};
restartOffset = null;
}
if (typeof input === 'string') {
if (!options) {
return promisifiedClientMethods.fastPut(input, destPath);
}
input = fs.createReadStream(input);
}
return promisifiedClientMethods.createWriteStream(destPath, options).then(function(stream) {
finishLogic(stream);
stream.on('error', (err) => {
reject(err);
});
input.on('end', () => {
resolve();
});
if (input instanceof Buffer) {
stream.end(input);
resolve();
return;
}
input.pipe(stream);
});
});
};
Please make this error message include the actual filename in it.
This fix would be awesome! Currently I have no way to catch those underlying stream errors and they make my process crash. Thanks for this great library!
Originally from: https://github.com/realtymaps/promise-ftp/issues/19
This exception is actually from promise-sftp library. However promise-sftp is not letting users create an issue.
Here is a code snippet to reproduce the error:
Since the path does not exist on the ftp server, the promise should be rejected. It is resolving successfully and throwing an error when we attempt to end the connection.
Output: