Ad
Node.js [promise-ftp] - Unable To Make Data Connection (Error: Connect ECONNREFUSED...) While Downloading Multiple Files From FTP
I'm getting this error while trying to download multiple images from ftp
using promise-ftp. I'm able to see some images being downloaded before this error.
Unable to make data connection( Error: connect ECONNREFUSED...)
In my scenario, client sends specific directory paths of ftp from which all the images should be downloaded to server.
Here is my code:
iniatially uploadData
consists of data from client from which directory paths are obtained.
router.post("/addPhotos", async (req, res) => {
try {
let uploadData = req.body;
if (!uploadData) {
handleError("Error! Invalid data received.", res);
return;
}
await getPhotosWithCaptionsAndPath(uploadData)
.then(uDataWithCaptionsAndPath => {
uploadData = uDataWithCaptionsAndPath;
res.status(200).send({
data: "Images Uploaded successfully!",
success: true,
error: null
});
})
.catch(err => {
handleError(err, res);
});
//insert uploadData to db . . .
} catch (err) {
handleError(err, res);
}
});
getPhotosWithCaptionsAndPath = uploadData => {
return new Promise(async (resolve, reject) => {
try {
let output = [];
let fileCount = 0;
//get total # of images in all directories
await getfileCount(uploadData)
.then(fc => (fileCount = fc))
.catch(err => reject(err));
//download images and generate output array for db rows
const ftp = new PromiseFtp();
await ftp
.connect({
host: env.ftp.host,
user: env.ftp.user,
password: env.ftp.password
})
.then(serverMessage => {
//looping through each directory
uploadData.forEach(async (v, i) => {
// calc directory path
/* prettier-ignore */
let uri = `/${
v.schoolName
}/${
v.studentClass.toString()
}-${
v.studentSection
}/${
v.studentName
}`;
await ftp
.list(uri, false)
.then(list => {
//looping through each image file
list.forEach((val, index) => {
uploadFtpFile(ftp, uri, val, output)
.then(outputFromUFF => {
output = outputFromUFF;
if (fileCount === output.length) {
ftp.end();
resolve(output);
}
})
.catch(err => reject(err));
});
})
.catch(err => reject(err));
});
});
} catch (err) {
reject(err);
}
});
};
uploadFtpFile = (ftp, uri, val, output) => {
return new Promise((resolve, reject) => {
try {
ftp.get(uri + "/" + val.name).then(stream => {
let fileName = `ph${Date.now()}.png`;
let file = fs.createWriteStream("./uploads/" + fileName);
output.push({
url: fileName,
caption: val.name.replace(/\.[^/.]+$/, "")
});
stream.pipe(file);
stream.once("close", () => {
resolve(output);
});
stream.once("error", reject);
});
} catch (err) {
reject(err);
}
});
};
getfileCount = uploadData => {
return new Promise((resolve, reject) => {
try {
let fileCount = 0;
const ftpC = new PromiseFtp();
ftpC
.connect({
host: env.ftp.host,
user: env.ftp.user,
password: env.ftp.password
})
.then(serverMessage => {
uploadData.forEach(async (v, i) => {
/* prettier-ignore */
let uri = `/${
v.schoolName
}/${
v.studentClass.toString()
}-${
v.studentSection
}/${
v.studentName
}`;
await ftpC
.list(uri, false)
.then(async list => {
fileCount += list.length;
if (i === uploadData.length - 1) resolve(fileCount);
})
.catch(err => reject(err));
});
})
.catch(err => reject(err));
} catch (err) {
reject(err);
}
});
};
Ad
Answer
There is a limit that is applied to FTP, so its not a good idea to bulk upload/download stuff from FTP, you need to convert your foreach
loops to for
loops this will allow each file to be processed in sequence, this may delay your process, but will be fail safe.
So you may change this snippet
for (let i = 0; i < list.length; i++) {
let val = list[i]
uploadFtpFile(ftp, uri, val, output)
.then(outputFromUFF => {
output = outputFromUFF;
if (fileCount === output.length) {
ftp.end();
resolve(output);
}
})
.catch(err => reject(err));
}
Ad
source: stackoverflow.com
Related Questions
- → How to update data attribute on Ajax complete
- → October CMS - Radio Button Ajax Click Twice in a Row Causes Content to disappear
- → Octobercms Component Unique id (Twig & Javascript)
- → Passing a JS var from AJAX response to Twig
- → Laravel {!! Form::open() !!} doesn't work within AngularJS
- → DropzoneJS & Laravel - Output form validation errors
- → Import statement and Babel
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM
Ad