I'm building something that includes javascripts on the fly asynchronously, which works, but I'm looking to improve upon the error detection (so all the errors don't just appear to come from some line near the AJAX call that pulls them down.
If I'm using eval to evaluate a multiline javascript file, is there any way to trace which line an error occurs on?
By keeping references to the variables I need when including, I have no problem determining which file the errors occurs in. My problem is determining which line the error occurs in.
Example:
try {
eval("var valid_statement = 7; \n invalid_statement())))");
} catch(e) {
var err = new Error();
err.message = 'Error in Evald Script: ' + e.message;
err.lineNumber = ???
throw err;
}
How can I tell that the error occurred in the second line there?
Specifically I'm interested in doing this in Firefox.
I know that error objects have e.stack in Mozilla browsers, but the output doesn't seem to take into account newlines properly.
The line number in an evaled script starts from the one the eval is on.
An error object has a line number of the line it was created on.
So something like...
try {
eval('var valid_statement = 7; \n invalid_statement())))');
} catch(e) {
var err = e.constructor('Error in Evaled Script: ' + e.message);
// +3 because `err` has the line number of the `eval` line plus two.
err.lineNumber = e.lineNumber - err.lineNumber + 3;
throw err;
}
The global error event-listener will catch the exception from eval and shows the correct line numbers (maybe not in all browsers):
window.addEventListener('error', function(e) {
console.log(e.message
, '\n', e.filename, ':', e.lineno, (e.colno ? ':' + e.colno : '')
, e.error && e.error.stack ? '\n' : '', e.error ? e.error.stack : undefined
);
}, false);
I don't think you can do it with eval reliably. However, you can do this instead of eval:
try {
$("<script />").html(scriptSource).appendTo("head").remove();
} catch (e) {
alert(e.lineNumber);
}
Join the window.addEventListener('error', ...) with document.createElement('script') works for me:
window.addEventListener('error', function(e) {
console.log('Error line:', e.lineno)
}, false);
function runCode (code) {
let js = document.createElement('script')
try {
js.innerHTML = code
document.head.appendChild(js)
}
catch(e) {
// ...
}
document.head.removeChild(js)
}
runCode('// try this:\n1ss') // prints 'Error line: 2'
Thanks to #frederic-leitenberger and #fromin for the solutions parts.
Related
I have the following code where I am using VAST player to play my ads.
I am using a check to see if the user has clicked already to avoid the DOM exception that is present in modern browsers.
(function(VASTPlayer) {
'use strict';
var player = new VASTPlayer(document.getElementById(playerID));
player.once('AdStopped', function() {
console.log('Ad finished playback! ' + playerID);
interstitialInstance.close();
});
player.load( << Ad Tag >> ).then(function startAd() {
console.log(player.adDuration + " " + playerID);
var s = document.getElementById(playerID).childNodes[0];
if (s) {
if (!ryads.mouseClick) {
s.muted = true;
} else
s.muted = false;
} else {
console.log("Error while fetching video element!!!");
}
return player.startAd();
}).catch(function(reason) {
console.log('Ad failed to play ' + playerID);
interstitialInstance.close();
setTimeout(function() {
throw reason;
}, 0);
});
}(window.VASTPlayer));
I am getting the following error when I run the Compress job in Jenkins.
project.js:891: ERROR - Parse error. missing name after . operator
}).catch(function(reason) {
^
project.js:892: ERROR - Parse error. syntax error
console.log('Ad failed to play '+playerID);
^
project.js:896: ERROR - Parse error. missing ; before statement
}(window.VASTPlayer));
This is a well known issue since years for yuicompressor.
An easy fix for is to extract the resolve and reject functions of the promise like this:
promise.then(successFunction, failureFunction);
function successFunction() {
console.log('success');
}
function failureFunction(err) {
console.error(err);
}
Replace this line
(function(VASTPlayer) {
by
;(function(VASTPlayer) {
Otherwise, when the compression job is trying to concatenate files, your IIFE might be considered an argument to the code that the end of the file contained which was concatenated right before this file.
Can you please elaborate on what
player.load( << Ad Tag >>
is? That is not valid Javascript. Some sort of JSX dialect? Or just a copy/paste error?
I am trying to call a stored procedure in java from my .xsjs file. The procedure gets 2 input parameters and returns one. I can call it from an SQL console without any problem by writing:
call "MYSCHEMA"."MyPackage.procedures::addUserC50" ('name', 'lastname', ?)
This is the code in my .xsjs file, I think that it fails in the prepareCall statement. I have tried different combinations (with and without double quotation marks, with and without the name of the schema/package, with and without "(?,?,?)", with and without "{ }".... But nothing works, I always get the 500 Internal server error when I try to execute it.
Does anybody know where the error is or what is the exact syntax for the prepareCall method?
var output = 0,
query = "";
var conn;
var cstmt;
try {
conn = $.db.getConnection();
query = "{ call \"MYSCHEMA\".\"MyPackage.procedures/addUserC50\"(?,?,?) }";
cstmt = conn.prepareCall(query); // <-- Fails
cstmt.setString(1, userName);
cstmt.setString(2, userLastname);
cstmt.execute();
output = cstmt.getInteger(3);
conn.commit();
$.response.status = $.net.http.OK;
$.response.setBody("Successfully created: " + output);
}
catch (e) {
$.response.status = $.net.http.BAD_REQUEST;
$.response.setBody("0");
}
finally {
if (cstmt !== null)
cstmt.close();
if (conn !== null)
conn.close();
}
This is the error that gives back: InternalError: dberror(Connection.prepareCall): 328 - invalid name of function or procedure: MyPackage.procedures/addUserC50: line 1 col 18 (at pos 17) at ptime/query/checker/check_call.cc:21
According to this documentation, it should be something like
var myCallableStatement = myconnection.prepareCall("{call myprocedure(?)}");
Thank you
I managed to make it run, this is the syntax that worked:
query = "call \"MyPackage.procedures::addUserC50\"(?, ?, ?)";
Thank you for your help #shofmn
There could be different reasons why the call is failing. You can investigate your error much easier if you return the error message in the HTTP response. You can do this easily:
try {
// Your code execution here
}
catch (e) {
$.response.contentType = "text/html";
$.response.setBody(e.name + ": " + e.message));
}
If the error message doesn't help you solving the problem, paste the error message in here so that it is more easy for us to investigate as well.
When a piece of javascript code gives an error in the console. How can I do something like: If this piece of code gives back an error execute another piece of code?
This is what I have:
try {
var operator = <?=$this->shopRequest[operator]?>;
} catch(errorObj) {
var operator = sessionStorage.getItem('operator');
}
This is the error I get in the console:
Uncaught SyntaxError: Unexpected token ;
Try:
var operator = "<?=$this->shopRequest[operator]?>";
alert(operator);
Edit
of better:
var operator = "<?=str_replace('"', '\"', $this->shopRequest[operator])?>";
just in case it will contain " symbols
If I understood correctly your answer you should use
try {
// your code
} catch(e) {
console.err('Ops ' + e);
// execute here other code
}
You can do something like this:
try
{
// Run some code here
}
catch(err)
{
// Handle errors here; You can make a call to the other piece of code from here
}
how can I find the error
try {
undef
} catch (e){
console.log(e)
console.dir(e)
}
the information bust be there somewhere, because the console.log (in firebug) includes:
ReferenceError: undef is not defined
but when I browse the e object, I can't find it.
How do I find out what the error is programmatically, so I can handle the error accordingly?
Edit:
try {
if(typeof undef == 'undefined'){
console.log('We should not access this "undef" var');
}
console.log('The next line will produce an exception');
undef
} catch (e){
console.log(e);
for(index in e){
console.log(index+' ('+(typeof e[index])+'): '+ e[index]);
}
}
Which will produce:
We should not access this "undef" var
The next line will produce an exception
ReferenceError: undef is not defined
fileName (string): file:///B:/xampp/htdocs/study/test.html
lineNumber (number): 12
stack (string): #file:///B:/xampp/htdocs/study/test.html:12
I don't think you can pull its type explicitly, but you can test it:
try {
undef
} catch (e){
console.log(e)
console.dir(e)
if(e instanceof ReferenceError) {
console.log("Ooops! Fat fingers!");
}
}
But of trial and error gives me this...
try {
undef
} catch (e){
console.log(e.toString())
// ReferenceError: undef is not defined
}
I guess firebug is just accessing the .toString() method of e
Edit:
I am guessing the .toString() method just concatenates the only two properties that are guaranteed cross browser - name and message - so I think e.message is the only reliable and useful piece of information to go with.
I want to catch exceptions in javascript if an insertion query is not done.
I have written the code below:
var adoConn = new ActiveXObject("ADODB.Connection");
var adoRS = new ActiveXObject("ADODB.Recordset");
var rec = new ActiveXObject("ADODB.Record");
adoConn.Open="DRIVER={MySQL ODBC 3.51 Driver};SERVER=172.25.37.145;" + "DATABASE=confluence;UID=root;PASSWORD=somePassword;OPTION=3";
//Connectionstring
alert('Database Connected');
adoConn.Execute("insert into `session` (SessionId,Timestamp) values ('"+SessionId+"','"+SessionCurrenttime+"')");
If I get the same session id then the query was not executed as it is the primary key in the database.
To be complete, here's the full structure
try {
// your code that can throw exception goes here
} catch(e) {
//do stuff with the exception
} finally {
//regardless if it worked or not, do stuff here (cleanup?)
}
<script language="JavaScript">
try
{
colours[2] = "red";
}
catch (e)
{
alert("Oops! Something bad just happened. Calling 911...");
}
</script>
(Ripped from http://www.devshed.com/c/a/JavaScript/JavaScript-Exception-Handling/)
try {
// your code that can throw exception goes here
} catch(e) {
//do stuff with the exception
}
FYI - the code you posted looks, well, for want of a better word, ugly! (No offense) Couldn't you use DWR or some other JavaScript framework (depending on your language choice) to hide all the DB connection stuff at the back end and just have the javascript calling the back end code and doing something with the response?
try {
adoConn.Execute("insert into session (SessionId,Timestamp) values ('"
+ SessionId + "','"
+ SessionCurrenttime + "')");
} catch(e) {
/*use error object to inspect the error: e.g. return e.message */
}