How to capture ftp-client connect attempt errors - node.js

I use the npm package ftp-client to download files from an ftp server. I cannot determine how to capture possible errors when attempting to connect to the remote server. Documentation on the ftp-client package is very sparse.
Can anyone help?
My code is below. As it stands any connection error (e.g. invalid password) just crashes the application.
const ftpClient = require('ftp-client');
require('dotenv').config();
const dtf_login = process.env.dtf_login;
const dtf_psw = process.env.dtf_psw;
const dtf_host = process.env.dtf_host;
function doDirDownload(remoteDir, localDir, callback){
var ftpOptions = {logging : 'none', overwrite : 'all'};
var ftpConfig = {host : dtf_host,
port : 21,
user : dtf_login,
password : dtf_psw};
c = new ftpClient(ftpConfig, ftpOptions);
c.connect((err) => {
if(err){
callback(err);
} else {
c.download(remoteDir, localDir,
{overwrite: 'all'}, (result) => {
callback(result);
});
}
});
}

Related

Code that worked on Replit doesn’t work in VSC

Basically, my code worked completely fine in replit, but now it doesnt work in a vsc folder. my replit version also suddenly can’t send any messages anymore. it sends all the console.logs but the client.say stuff it just skips without an error.
const tmi = require('tmi.js');
// Define configuration options
const opts = {
identity: {
username: 'BormBot',
password: 'cut out for a reason'
},
channels: [
'Epicurious__'
]
};
// Create a client with our options
const client = new tmi.client(opts);
const jsonFile = require('./link.json');
const fs = require('fs');
const mongoose = require('mongoose');
// Register our event handlers (defined below)
client.on('connected', onConnectedHandler);
// Connect to Twitch:
client.connect();
client.on('message', (channel, tags, msg, self, target) => {
if (self) return;
//start of geoguessr commands
const link = {
"link": ""
};
if (msg.startsWith('!geolink')) {
if (tags.badges.broadcaster == 1) {
const arguments = msg.split(/[ ]+/)
if (arguments[1]) {
let link = arguments[1];
const data = JSON.stringify(link);
fs.writeFile('./link.json', data, (err) => {
if (err) {
throw err;
}
console.log("JSON data is saved.");
});
client.say(channel, link);
} else {
console.log("no args");
}
}
}
if (msg.startsWith('!game')) {
// read JSON object from file
fs.readFile('./link.json', 'utf-8', (err, data) => {
if (err) {
throw err;
}
// parse JSON object
const linkDone = JSON.parse(data.toString());
// print JSON object
client.say(channel, `The link for the current geoguessr game is: ${linkDone}`);
console.log(`${linkDone}`);
});
}
//end of geoguessr commands
});
// Called every time the bot connects to Twitch chat
function onConnectedHandler(addr, port) {
console.log(`* Connected to ${addr}:${port}`);
}
console
Also on twitch developer forum: 2
On twitch developer forum there hasn't been an answer yet, hence why I'm also putting it on here. Hopefully I can find an answer, also, maybe add a tag for tmi.js

Unable to connect to oracle cloud autonomous database from linux environment

I am using a Node JS application that has Oracle Autonomous Database as a backend.
It works perfectly on my local machine and I am able to connect it well without any issue.
I tried deploying Node JS project to Azure WebAppService on Linux server.
Initially after deployment I my project was not able to find the Oracle client and so after searching a lot I was able to fix that problem by below
steps
with this I was able to solve client issue.
I have wallet files which I received from oracle which I have placed in admin folder
but now the problem is when I make any request I am getting this error
data:{"message":"db.doConnect is not a function","stack":"TypeError:
db.doConnect is not a `function\n`
createPool() callback: ORA-28759: failure to open file
my code:
// Include all external dependencies
const oracledb = require('oracledb');
// Intialize variables
const numRows = 100;
let respArr = [];
let connectionObject;
async function initialize(envName) {
await oracledb.createPool({
user: process.env.DATABASEUSERNAME,
password: process.env.DATABASEPASSWORD,
connectString: process.env.DATABASECONNECTIONSTRING,
});
}
async function close(poolAlias) {
await oracledb.getPool(poolAlias).close();
}
// Function to iterate through all the rows fetched in the result set and resturn the same
async function fetchRowsFromRS(connection, resultSet, numRows) {
// Get the rows
try {
const rows = await resultSet.getRows(numRows);
// no rows, or no more rows, then close the result set
if (rows.length === 0) {
console.log('No rows returned');
// doClose(connection, resultSet);
} else if (rows.length > 0) {
console.log(`Got ${rows.length} rows`);
respArr = respArr.concat(rows);
// Call the function recursively to get more rows
await fetchRowsFromRS(connection, resultSet, numRows);
}
// Return the rows
return respArr;
} catch (err) {
console.log(err);
}
}
async function simpleExecute(statement, binds = [], numberOutCur, poolAlias, opts = {}) {
try {
await initialize();
opts.outFormat = oracledb.OBJECT;
opts.autoCommit = true;
connectionObject = await oracledb.getConnection(poolAlias);
const finalResult = {};
const result = await connectionObject.execute(statement, binds, opts);
let promises = [];
for (let idx = 0; idx < numberOutCur; idx++) {
const refCurName = `ref_cur_${idx}`;
promises.push(fetchRowsFromRS(connectionObject, result.outBinds[refCurName], numRows));
const resultRows = await Promise.all(promises);
respArr = [];
finalResult[refCurName] = resultRows;
promises = [];
}
return finalResult;
// const values = await Promise.all(promises);
// return values;
} catch (error) {
return error;
} finally {
if (connectionObject) {
try {
await connectionObject.close();
} catch (err) {
console.log(err);
}
}
}
}
// Function to release the connection
function doRelease(connection) {
connection.close(
(err) => {
if (err) {
console.log(err.message);
}
},
);
}
// Function to close the result set connection
function doClose(connection, resultSet) {
resultSet.close(
(err) => {
if (err) { console.log(err.message); }
doRelease(connection);
},
);
}
// Export functions
module.exports.simpleExecute = simpleExecute;
module.exports.initialize = initialize;
module.exports.close = close;
I call my procs using this
const allProducts = await dbSvc.simpleExecute(query, cart_data_binds, 1,
'default');
what I understood with this message is I am not able to connect to my cloud database and I am not sure how to solve this can anyone help me with it its been 2 weeks now with this problem.
In Node JS project I am using simpleoracle library to connect my oracle cloud anonymous database
Thank you, Christopher Jones and saiharika213. Posting your suggestions as an answer to help other community members.
This ORA-28759: failure to open file error seems you need to update the WALLET_LOCATION directory in sqlnet.ora. You can refer to Connecting to Oracle Cloud Autonomous Databases
You can resolve this error by changing the connection string to point to the wallet location.
Move the wallets to respective project folder and modify the connection string as below in dbConfig.js.
Provide the wallet path from root till wallet folder.
For example:
module.exports = {
user: username,
password:password,
connectString:"(DESCRIPTION = (ADDRESS = (PROTOCOL = TCPS)(HOST = Hostname )(PORT = XXXX))(CONNECT_DATA = (SERVER = DEDICATED)(SERVICE_NAME = Servicename))(SECURITY=(MY_WALLET_DIRECTORY=/Users/yharika/Node_Projects/invoice_app/config/wallet)))"
}
You can refer to Unable to connect to oracle database from node js using sqlnet.ora with oracle wallet and Connecting with TCPS - ora-28759: failure to open file

Intent handler failed with error: Buffer is not defined

I have built a Google Smart Home Action using the Local Fulfillment SDK as outlined in the following articles:
https://developers.google.com/assistant/smarthome/develop/local
https://github.com/actions-on-google/create-local-home-app
I am using UDP for device discovery and my Google Nest Hub can successfully scan and detect the virtual device running on my laptop as well as download the JS of the local app.
My Local Home SDK configuration is as follows - Local Home SDK Configuration.
When the Nest Hub executes the IDENTIFY intent of my app handler I am receiving the following error(s):
[smarthome.DeviceManager] Intent handler failed with error: Buffer is not defined
[smarthome.DeviceManager] Got a rejected promise Buffer is not defined
This appears to be a Node.JS error as opposed to something specific to the local SDK app itself. Below is the code of my local app.
/// <reference types="#google/local-home-sdk" />
import App = smarthome.App;
import Constants = smarthome.Constants;
import DataFlow = smarthome.DataFlow;
import Execute = smarthome.Execute;
import Intents = smarthome.Intents;
import IntentFlow = smarthome.IntentFlow;
const SERVER_PORT = 3388;
interface ILightParams {
on?: boolean,
brightness?: number
}
class LocalExecutionApp {
constructor(private readonly app: App) { }
identifyHandler(request: IntentFlow.IdentifyRequest):
Promise<IntentFlow.IdentifyResponse> {
console.log("IDENTIFY intent: " + JSON.stringify(request, null, 2));
const scanData = request.inputs[0].payload.device.udpScanData;
console.log("SCANDATA: " + JSON.stringify(scanData));
if (!scanData) {
const err = new IntentFlow.HandlerError(request.requestId, 'invalid_request', 'Invalid scan data');
return Promise.reject(err);
}
const localDeviceId = Buffer.from(scanData.data, 'hex');
console.log("ScanData Local Device: " + localDeviceId);
const response: IntentFlow.IdentifyResponse = {
intent: Intents.IDENTIFY,
requestId: request.requestId,
payload: {
device: {
// id: localDeviceId.toString(),
id: 'sample-device',
verificationId: localDeviceId.toString(),
}
}
};
console.log("IDENTIFY response: " + JSON.stringify(response, null, 2));
return Promise.resolve(response);
}
executeHandler(request: IntentFlow.ExecuteRequest):
Promise<IntentFlow.ExecuteResponse> {
console.log("EXECUTE intent: " + JSON.stringify(request, null, 2));
const command = request.inputs[0].payload.commands[0];
const execution = command.execution[0];
const response = new Execute.Response.Builder()
.setRequestId(request.requestId);
const promises: Promise<void>[] = command.devices.map((device) => {
console.log("Handling EXECUTE intent for device: " + JSON.stringify(device));
// Convert execution params to a string for the local device
const params = execution.params as ILightParams;
const payload = this.getDataForCommand(execution.command, params);
// Create a command to send over the local network
const radioCommand = new DataFlow.HttpRequestData();
radioCommand.requestId = request.requestId;
radioCommand.deviceId = device.id;
radioCommand.data = JSON.stringify(payload);
radioCommand.dataType = 'application/json';
radioCommand.port = SERVER_PORT;
radioCommand.method = Constants.HttpOperation.POST;
radioCommand.isSecure = false;
console.log("Sending HTTP request to the smart home device:", payload);
return this.app.getDeviceManager()
.send(radioCommand)
.then(() => {
const state = {online: true};
response.setSuccessState(device.id, Object.assign(state, params));
console.log(`Command successfully sent to ${device.id}`);
})
.catch((e: IntentFlow.HandlerError) => {
e.errorCode = e.errorCode || 'invalid_request';
response.setErrorState(device.id, e.errorCode);
console.error('An error occurred sending the command', e.errorCode);
});
});
return Promise.all(promises)
.then(() => {
return response.build();
})
.catch((e) => {
const err = new IntentFlow.HandlerError(request.requestId, 'invalid_request', e.message);
return Promise.reject(err);
});
}
/**
* Convert execution request into a local device command
*/
getDataForCommand(command: string, params: ILightParams): unknown {
switch (command) {
case 'action.devices.commands.OnOff':
return {
on: params.on ? true : false
};
default:
console.error('Unknown command', command);
return {};
}
}
}
const localHomeSdk = new App('1.0.0');
const localApp = new LocalExecutionApp(localHomeSdk);
localHomeSdk
.onIdentify(localApp.identifyHandler.bind(localApp))
.onExecute(localApp.executeHandler.bind(localApp))
.listen()
.then(() => console.log('Ready'))
.catch((e: Error) => console.error(e));
Any insight on why this error is occurring is greatly appreciated.
Cheers.
Reposting the answer in the comments:
Buffer is not a type that is directly supported in a browser environment. You can see this for yourself by trying to run something like x = new Buffer() in your web browser's dev console.
To support a class like Buffer, you can use a bundling tool like Webpack. In the official sample, you can see an example Webpack configuration. Other bundling tools can also be used, and examples can be found in the official Local Home scaffolding tool or can be called directly with an npm init command.
npm init #google/local-home-app app/ --bundler webpack
npm init #google/local-home-app app/ --bundler rollup
npm init #google/local-home-app app/ --bundler parcel

Custom Search API works on local host but request timeout on Heroku

I am currently building an image search api with code as follows:
When i try to run in on local using heroku local in terminal, it works as expected, i.e when i enter the following url into the browser:
http://localhost:5000/api/imagesearch/1984
It returns the desired search results. However, when the app is deployed on Heroku and i run the app using heroku open, I get an Application Error. I have checked the log and it seems like it is a H12 request timeout error.
It seems to me that the app is taking a very long time (much longer than when i run it on localhost such that there is a request timeout error) to get a response from google custom search when I am accessing using Heroku compared to when i am accessing via local host but i am unable to figure out why that is the case or what else can i do to work this issue.
Would really appreciate some guidance. Thanks
var Search = require('../models/history.js');
var GoogleSearch = require('google-search');
var googleSearch = new GoogleSearch({
key: "XXXX",
cx: "YYY"
});
function ImgSearchHandler () {
this.retrieveSearchResults = function (req, res) {
var newSearch = new Search();
newSearch.term = req.params.query;
newSearch.when = new Date();
newSearch.save(function (err){
console.log("saving...");
if (err) {throw err;}
var offset;
if (req.query.offset) {
offset = req.query.offset;
} else {
offset = 1;
}
//res.send('save and retrieve');
googleSearch.build({
q: req.params.query,
searchType: "image",
fileType:'png jpg gif jpeg',
num: 1, // Number of search results to return between 1 and 10, inclusive
start: offset,
}, function(error, response) {
if (error) {
throw error;
}
var results = [];
response.items.forEach(function (element){
var url = element.link;
var context = element.image.contextLink;
var snippet = element.snippet;
var thumbnail = element.image.thumbnailLink;
var result = {url: url, snippet: snippet, thumbnail: thumbnail, context: context};
results.push(result);
});
res.json(results);
//res.json(response.items);
});
});
}
}
module.exports = ImgSearchHandler;

Simple soap call is failing (Nodejs, easysoap)

I am having some problems with easysoap (https://npmjs.org/package/easysoap) and I have been unable to find much documentation or people talking about it, so I hope some of you can help:
I’m making a simple call like this:
var clientParams = {
host : 'somewhere.com',
port : '9001',
path : '/somews.asmx',
wsdl : '/somews.asmx?WSDL'
};
var clientOptions = {
secure : false
};
//create new soap client
var SoapClient = new soap.Client(clientParams, clientOptions);
SoapClient.once('initialized', function() {
//successful initialized
SoapClient.once('soapMethod', function(data, header) {
});
console.log('call');
SoapClient.call({
'method' : 'Execute',
'params' : {
'ExecuteXML' : 1
}}, function(attrs, err, responseArray, header){
}
);
});
//initialize soap client
SoapClient.init();
The problem Is that I get a response saying that I am not authorized to make my request.However if I manually try the same url in the browser http://somewhere.com:9001/somews.asmx it does work.
Do you know what am I doing wrong?
Many many thanks in advance.
If any of you know of any other node module to achieve this please let me know. I attempted to use node-soap but got lost in all the dependencies required: python, Visual Studio... you really need all that to make a couple of soap calls to a server???
Thanks
For other nodejs soap modules. I currently use node-soap and am happy with it. You can find the project here.
Here is an example of how I'm using it.
var soap = require('soap');
//example url
var url = 'http://ws.strikeiron.com/GlobalAddressVerification5?WSDL';
var soapHeader = ''//xml string for header
soap.createClient(url, function(err, client){
client.addSoapHeader(soapHeader);
var args = {
StreetAddressLines: "5322 Otter Lane",
CountrySpecificLocalityLine: "Middleberge FL 32068",
Country: "USA"
};
client.BasicVerify(args, function(err, result){
if(err){
throw err;
}
console.log(result);
});
});
For me this worked:
"use strict";
var easysoap = require('easysoap');
var clientParams = {
host : 'http://somewhere.com:9001',
path : '/somews.asmx',
wsdl : '/somews.asmx?WSDL'
};
var clientOptions = {
secure : false
};
var soapClient = easysoap.createClient(clientParams, clientOptions);
soapClient.call({'method' : 'Execute',
'params' : {
'ExecuteXML' : 1
}})
.then(function (callResponse) {
console.log(callResponse);
})
.catch(function (err) {
console.log("Got an error making SOAP call: ", err);
});

Resources