I am confused about the Javascript exception handling I wanted to clear which error can Javascript catch or which can only be handling with if elses
like in case below in first case I end up into catch block because of undefined variable but in other case I stayed in the try block(and would have to use if else for catching that) inspiteof both are "not defined"
first:
try {
var x = 90;
var value = x / y;
}
catch (err) {
document.write(err.name + ": " + err.message + "<br/>");
}
second :
function add(x, y) {
var resultString = "Hello! The result of your math is: ";
var result = x + y;
// return resultString + result; not returning anything; hence, "undefined" also
}
try {
var addResult = add(2, 3);
document.write(" the result is : " + addResult + "<br/>");
} catch (err) {
document.write(err.name + ": " + err.message + "<br/>");
}
Why I am not ending up in to catch block in second case also?
Please clear my understanding.
In the first case you have not defined y anywhere so that throws an exception which is been caught by the catch block, But in the second case you have defined addResult=undefined and you are just displaying the value, so there is no exception
If your first case was
try {
var x = 90;
var y = undefined;
var value = x / y;
}
catch (err) {
document.write(err.name + ": " + err.message + "<br/>");
}
Then there would have been no exception in first case also.
Hope you got it :)
Because there aren't any errors in the second example. The only issue is that addResult doesn't return anything, which leads to the undefined value. However, this is not an error.
Your first example catches an exception just because the y variable wasn't event declared (it doesn't even has the undefined value).
You can see this in action here:
<script type="text/javascript">
//Error
try{
alert(x);
}catch(e){
alert(e.name + ': ' + e.message);
}
//Ok
try{
var x;
alert(x);
}catch(e){
alert(e.name + ': ' + e.message);
}
</script>
Related
I want to use the return of a query to a postgresSQL database. I don't want to just print it. I want to use it in another function. The problem is that the function here returns before it is finished with executing the code.
async function create_base_config(user_id, service_id, timer_seconds) {
var ret
var line
await db_adm_conn.query(`
INSERT INTO base_config (user_id, service_id, timer_seconds)
VALUES ('` + user_id + "', '" + service_id + "', '" + timer_seconds + "') RETURNING id;", (err, result) => {
if (err) {
ret = false
line = err
console.log("line2 err : " + line)
}
else {
ret = true
line = result.rows
console.log("line2 : " + line)
// json_return = JSON.parse(result)
// console.log(result.rows)
}
});
console.log("line: " + line)
return { ret_value: ret, line_value: line };
}
To test it i inserted debug prints. The output is:
server_1 | line: undefined
server_1 | line2 : [object Object]
so I am exectuting the code after the await before the await is finished. How can i fix that, so that he first executes all the code from the await and then the rest?
you should not use a callback function as the arrow function. You should use try catch like this:
async function create_base_config(user_id, service_id, timer_seconds) {
var ret
var line
try {
line = await db_adm_conn.query(`
INSERT INTO base_config (user_id, service_id, timer_seconds)
VALUES ('` + user_id + "', '" + service_id + "', '" + timer_seconds + "') RETURNING id;")
ret = true
}
catch (err) {
ret = false
line = err
}
return { ret_value: ret, line_value: line };
}
I am trying to run the following code which loops through some data from a previous step and then calls a POST fetch command and I am getting the vague "'NoneType' object does not support item assignment" error when I test in Zapier. I have contacted them about it and they cannot support my code and cannot provide any better data on what's happening.
Any ideas?
CODE START
var noteEmail;
var noteSubject;
var noteDescription;
function attachNote() {
fetch ('https://xyzdomain.agilecrm.com/dev/api/contacts/email/note/add', options)
.then(function(res) {
return res.json();
})
.then(function(json) {
callback(null, json);
})
.catch(callback);
}
var headers = {
'Accept': 'application/json',
'Content-Type ': 'application/x-www-form-urlencoded'
};
var dataString = 'email=' + noteEmail + '¬e={"subject":"' + noteSubject + '","description":"' + noteDescription + '"}';
var options = {
method: 'POST',
headers: headers,
body: dataString,
auth: {
'user': 'xyz#xyz.com',
'pass': 'password'
}
};
function callback(error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
}
//Get Rep name by Hubspot ID
function getRep(repNumber) {
switch (repNumber) {
case "12345678":
return "Steve Jenkins";
break;
case "90123456":
return "John Jenkins";
break;
default:
return "Dave Jenkins";
break;
}
}
var dataBody = inputData.Body.split(',');
var dataType = inputData.Type.split(',');
var dataEmailSubject = inputData.EmailSubject.split(',');
var dataCreatedAt = inputData.CreatedAt.split(',');
var dataCreatedBy = inputData.CreatedBy.split(',');
var dataMeetingTitle = inputData.MeetingTitle.split(',');
var dataStartTime = inputData.StartTime.split(',');
var dataEmailBody = inputData.EmailBody.split(',');
var dataEngagementId = inputData.EngagementId.split(',');
for (var i = 0; i < dataEngagementId.length; i++) {
switch (dataType[i]) {
case "NOTE":
noteSubject = "HS NOTE: - " + dataCreatedAt[i] + " - " + getRep(dataCreatedBy[i]);
noteDescription = dataBody[i];
attachNote();
break;
case "MEETING":
noteSubject = 'HS MEETING: - ' + dataStartTime[i] + " - " + getRep(dataCreatedBy[i]);
noteDescription = dataMeetingTitle[i];
attachNote();
break;
case "TASK":
noteSubject = 'HS TASK: - ' + dataCreatedAt[i] + " - " + getRep(dataCreatedBy[i]);
noteDescription = dataBody[i];
attachNote();
break;
case "CALL":
noteSubject = 'HS CALL: - ' + dataCreatedAt[i] + " - " + getRep(dataCreatedBy[i]);
noteDescription = dataBody[i];
attachNote();
break;
case "EMAIL":
noteSubject = 'HS EMAIL: - ' + dataCreatedAt[i] + " - " + getRep(dataCreatedBy[i]);
noteDescription = dataEmailSubject[i]; + ' - ' + dataEmailBody[i];
attachNote();
break;
case "INCOMING_EMAIL":
noteSubject = 'HS INCOMING EMAIL: - ' + dataCreatedAt[i] + " - " + getRep(dataCreatedBy[i]);
noteDescription = dataEmailSubject[i]; + ' - ' + dataEmailBody[i];
attachNote();
break;
default:
//Nothing matches do nothing
break;
}
}
David here, from the Zapier Platform team.
Your code is syntactically correct, so you're good to go there. Standard (my preferred js linter; powered by eslint) noted that there's some unreachable code, but that's not a showstopper. In your getRep function, you've got code after return (just break, no big deal) which will never be called. return quits the entire function, so it replaces the break you would normally need.
As for your actual issue, you're re-defining callback when you shouldn't be. There's docs on the issue, but the idea is that that's a function that lambda (where your code is run) defines. Redefining breaks the code runner.
Sorry for the confusion here! I'll see about throwing an error in the parser if you do this (or surfacing a better error).
Separately, I'm not positive this will do what you expect. Namely, you use noteSubject and noteDescription in dataString towards the top of the function, but modify it later. I don't think these changes will be shown in the options object. I haven't run your code though, so if fixing your callback redefinition makes everything work, ignore my suggestions. Also, to no-op the rest of the function, you can return [] per these docs.
Hope this helps. Let me know if you've got any other questions!
I am writing code to generate thumbnails based on user selected image manipulation actions which may be multiple as choosen by user using lwip npm package module.
For multiple actions lwip provides batch function and then chaining other manipulating functions.The problem i faced is that user may select any combination of host of manipulating functions and it is too cumbersome to check for each and every combinations of selected actions.
So, i have generated the code dynamically as js code string which i need to execute as function without using eval that may compromise application security
Below is my code
'use strict';
(function(uploadhandler){
var lwip=require('lwip'),
imageSettingProvider=require('../data/imagesettingprovider'),
uploadFolder='public/uploads/',
imageManipulatorHelper=require('./imagemanipulationactions'),
manipulatedImage='';
uploadhandler.generateThumbnail=function(filePath,filename,ImageUploadSetting,fs){
// compound effects
var thumbnailPath='';
lwip.open(filePath, function(err, image) {
if (err) {
console.log(err);
}else{
imageSettingProvider.getImageSetting(ImageUploadSetting,{},function(err,imageSettings){
imageSettings.forEach(function(element,index,array){
thumbnailPath=uploadFolder + element.folderName + '/' + filename;
var imageAction=element.action;
if(imageAction.indexOf(',')>-1){
var imageManipulationActions=imageAction.split(',');
var manipulationHtml='';
manipulationHtml += 'image.batch()';
var actionHtml='';
imageManipulationActions.forEach(function(actionelement,actionindex,actionarray){
actionHtml += uploadhandler.PerformMultipleImageManipulation(actionelement,element,actionHtml);
});
manipulationHtml += actionHtml;
console.log('----------------------------------------------------------------------------------------------------------');
manipulationHtml += '.writeFile(thumbnailPath, function(err) { if (err) throw err;});';
console.log(manipulationHtml);
}
});
});
}
});
};
uploadhandler.PerformMultipleImageManipulation=function(imageAction,imageOpts,actionHtml){
switch (imageAction){
case "crop":
actionHtml = '.crop(' + imageOpts.width + ',' + imageOpts.height + ')';
break;
case "cropbycoordinates":
actionHtml = '.crop(' + imageOpts.cropLeftPos + ',' + imageOpts.cropTopPos + ',' + imageOpts.cropRightPos + ',' + imageOpts.cropBottomPos + ')';
break;
case "resize":
actionHtml = '.resize(' + imageOpts.width + ',' + imageOpts.height + ')';
break;
case "resizecrop":
actionHtml = '.resize(' + imageOpts.width + ',' + imageOpts.height + ')' + '.crop(' + imageOpts.width + ',' + imageOpts.height + ')';
break;
case "rotate":
actionHtml = '.rotate(' + imageOpts.rotateDegree + ',' + imageOpts.backgroundColor + ')';
break;
case "blur":
actionHtml = '.blur(' + imageOpts.blurVal + ')';
break;
case "scale":
actionHtml = '.scale(' + imageOpts.scaleVal + ')';
break;
case "mirror":
actionHtml = '.mirror(' + imageOpts.flipAxes + ')';
break;
case "fade":
actionHtml = '.fade(' + imageOpts.fadeVal + ')';
break;
}
return actionHtml;
};
})(module.exports);
Now when i log the manipulation variable to the console,it gives:
image.batch()
.resize(480,320)
.crop(480,320)
.rotate(75,white)
.writeFile(thumbnailPath, function(err) {
if (err) throw err;
});
Now i need to execute this above js code string as function to generate thumbnail image without using javascript eval function.
I have tried using following approach from sitepoint website:
// function we want to run
var fnstring = "runMe";
// find object
var fn = window[fnstring];
// is object a function?
if (typeof fn === "function") fn();
But it gives me with the error " ReferenceError: window is not defined
"
Please guide me to solve this problem.
Fetch the actions into global object and execute each one using each particular function's namespace.
var helper = {};
helper.b = function() {
console.log("foo");
}
helper.c = function() {
console.log("bar");
}
//execute them
function execute(key) {
try {
helper[key]();
} catch (e) {
throw new Error("Function does not exist");
}
}
execute("b");
execute("c");
execute("d");
If it helps, you could run a regex replace function.
Note: I have not tested this.
// if worried about security with eval, you may want to put functions in an object instead of using global
const myFunctions = {
runMe: function(){/* do stuff */},
runMe2: function(){/* do stuff */}
};
const allowedFuncs = ['runMe', 'runMe2'];
// or dynamic to entire object
const allowedFuncs = Object.keys(myFunctions);
str = str.replace(new RegExp('(''+allowedFuncs.join('|')+)\\((.*?)\\)', 'g'), (str, func, attrs) => {
// check allowed list for added security
if(allowedFuncs.includes(func)){
attrs = attrs.split(',');
myFunctions[func](...attrs); // 3 dots makes js expand array to params separated by camas
}
return str; // returning str replaces nothing
});
bot.addListener('message', function (from, channel, message) {
IRClog.write("[" + (new Date()).toJSON() + "] [" + channel + "] <" + from + ">" + message + "\n");
// ============= PLAYER COMMANDS ============= //
if (logMessages){
util.log("[" + channel + "] <" + from + ">" + message);
}
console.log(message)// the message is logged
bot.whois(from,function(WHOIS){
if(typeof WHOIS.account == 'undefined'){
var isAuthed = false;
} else {
var isAuthed = true;
}
if (message.indexOf("!") === 0){//now the message is undefined
...
As described in the code, the var message is a string, and then, I don't know why, it becomes an undefined variable. Why is that happening? I didn't assign it to another value.
Depending on the execution context the function that the bot.whois executes may not have message defined in scope. You can use a closure to ensure the scope by passing in the message.
(function (msg) {
console.log(msg)// the message is logged
bot.whois(from, function(WHOIS){
var isAuthed = typeof WHOIS.account !== 'undefined';
if (msg.indexOf("!") === 0) {
...
}
})(message);
Your code is incomplete, obviously, and the actual bug probably resides somewhere below your cutoff point as you've put in your question:
bot.addListener('message', function (from, channel, message) {
IRClog.write("[" + (new Date()).toJSON() + "] [" + channel + "] <" + from + ">" + message + "\n");
// ============= PLAYER COMMANDS ============= //
if (logMessages){
util.log("[" + channel + "] <" + from + ">" + message);
}
console.log(message)// the message is logged
bot.whois(from,function(WHOIS){
if(typeof WHOIS.account == 'undefined'){
var isAuthed = false;
} else {
var isAuthed = true;
}
if (message.indexOf("!") === 0){//now the message is undefined
...
}); // end of the whois block, which is asynchronous
/* somewhere down here, message probably gets set to undefined
like this:
message = undefined; // this would run before bot.whois(from, cb); finishes
*/
}); // end of addListener
You either need to make sure that you're not messing with the message below your whois call, or you need to create a copy that you don't mess with, or you need to follow #Romoku's advice and wrap your whois call in a properly formatted closure (like the following) and pass message in to a strictly local scope:
bot.addListener('message', function (from, channel, message) {
IRClog.write("[" + (new Date()).toJSON() + "] [" + channel + "] <" + from + ">" + message + "\n");
// ============= PLAYER COMMANDS ============= //
if (logMessages){
util.log("[" + channel + "] <" + from + ">" + message);
}
console.log(message)// the message is logged
(function (msg) {
bot.whois(from,function(WHOIS){
if(typeof WHOIS.account == 'undefined'){
var isAuthed = false;
} else {
var isAuthed = true;
}
if (msg.indexOf("!") === 0){//now the message is undefined
...
}); // end of the whois block, which is asynchronous
})(message);
/* now you can do whatever you want to the message variable and bot.whois will
be able to operate on its independent, unmolested copy
*/
}); // end of addListener
Please note how in my example, and #Romoku's, message has been explicitly renamed (to msg and m, respectively), to make it clear that you're working with in a different scope with a different copy of the data.
i am trying to create a relational database while using oop in java script , yet i am encountered with some difficulties , this is the code ,
IT WAS WORKING BEFORE I CHANGED IT TO OOP
function DB() {
this.size;
this.row;
this.getsize = function() {
return this.size;
}
this.db = window.openDatabase('coupons', "1.0", 'database for coupons', 100000);
this.al = function() {
alert('al works');
}
this.add = function(table, id, name, email, fav) {
// alert("works");
// alert("INSERT INTO " + table + " VALUES(" + id + "," + name + ")");
this.db.transaction(function(ob)
{
ob.executeSql("SELECT * FROM " + table + " WHERE pid= " + id + "", [], this.dataHandler, this.errorHandler);
});
this.db.transaction(function(ob)
{
//alert(getsize());
if (this.size > 0) {
alert("user already exists")
} else {
ob.executeSql("CREATE TABLE IF NOT EXISTS " + table + " (pid INTEGER, pname TEXT, pemail TEXT,pfav)");
ob.executeSql("INSERT INTO " + table + " VALUES(" + id + "," + "'" + name + "'" + "," + "'" + email + "'" + "," + "'" + fav + "'" + ")");
alert("user addd successfuly");
}
}
);
}
this.errorHandler = function(error)
{
document.write("handling error " + error);
}
this.dataHandler = function(transaction, data)
{
// document.write("<table>");
//document.write("<tr><th>id</th><th>name</th></tr>")
// size = data.rows.length;
//for(i=0;i<size;i++)
// {
//Variables.call(this,data.rows.length,data.rows.item(0));
//Variables.call(7,6);
this.size = data.rows.length;
this.row = data.rows.item(0);
//return row;
// document.write(
// "<tr><td>"+row['pid']+"</td><td>"+row['pname']+"</td></tr>");
// }
//document.write("</table>");
}
this.getrows = function(n)
{
switch (n)
{
case 'pid':
return this.row['pid'];
break;
case 'pname':
return this.row['pname'];
break;
case 'pemail':
return this.row['pemail'];
break;
case 'pfav':
return this.row['pfav'];
break;
default:
}
}
}
the problem are as follows , hope you can help me out !!
1.after calling the function add , it does not go to dataHandler function .
2. in the add function i am unable to use local variables , how can i use the variable 'size' to check if the user exists in the database or not ?!! ,
hope you can help i have been in this code for 2 days !!! :(
Yes. You obviously can't access this.size in your function because you are using a anonymous function, so this is not related to your DB -oject but points to that anonymous function.
The same for your calls to this.dataHandler or this.errorHandler.
So you could just
this.db.transaction = function(ob)
to make it a method of your object which then will give you full access to the this - pointer of your DB - Object.
EDIT: Sorry, this would then point to the db object, of course, so this is not a solution.
But you can pass it your data - and errorHandler like this:
this.db.transaction(function() { ... }, this.errorHandler, this.dataHandler);
and avoid the call to this.size within the second transaction - statement by simply wrapping your call like:
if(this.size > 0) { alert('..'); } else { db.transaction(...) }
But: Your errorHandler and dataHandler must actually correspond to the right interface - definitions, take a look at:
http://www.w3.org/TR/2009/WD-html5-20090212/structured-client-side-storage.html