Is there such a thing as blocking vs non blocking Javascript errors?
What I mean is that I've seen my site report some errors, but the process involved still completes successfully (as far as I can tell). These errors include:
TypeError: undefined is not an object (evaluating 'e.nodeName.toLowerCase')
TypeError: e.nodeName is undefined
(these are always from my general JQuery library file)
These are what I mean by 'non-blocking' errors, since the scripts involved seem to complete successfully.
If there is such a thing as blocking v non-blocking, what is the correct terminology for it, and how can I tell the difference between the 2 (eg so that I can prioritise investigating blocking errors)?
Thanks
Whenever
throw Error;
The exception bubles up the function stack. If it reaches the end of it, it throws an uncaught (=unexpected) exception. This halts the complete program as its unlikely to work properly anymore.
However it can be catched (=expected exception):
try{
someerrorproducingfunc();
//continue after success
}catch(e){
//continue after error
console.error(e);
}
//continue after error+success
So the code proceeds ( leaving out the continue after sucess part). However, if you use console.error it logs sth that looks like an error.
ressource: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/throw
Note that Error is just an object constructor in js:
new Error("test");
While throw throws an exception...
No. All un-caught error are blocking, they will end the execution of the entire call stack. However, an error that happens after various operation will not revert back to a situation like before. Making an AJAX call, and then having an undefined error will not cancel the call for example. Demo:
(function () {
"use strict";
let a = 5;
console.log(a); // 5
setTimeout(function () {
console.log(a); // 10
// will execute because it is a fresh stack
// the variable a is 10 despite and not 12 because it happened after
}, 250);
const withError2 = function () {
a = 10;
a.x.z = 2; // Error
a = 12; // never executes because it comes after the error
}
withError2();
console.log(a); // never executes because it comes after the error
}());
Related
In some Node.js scripts that I have written, I notice that even if the last line is a synchronous call, sometimes it doesn't complete before Node.js exits.
I have never seen a console.log statement fail to run/complete before exiting, but I have seen some other statements fail to complete before exiting, and I believe they are all synchronous. I could see why the callback of an async function would fail to fire of course in this case.
The code in question is a ZeroMQ .send() call like so:
var zmq = require('zmq');
var pub = zmq.socket('pub');
pub.bindSync('tcp://127.0.0.1:5555');
setInterval(function(){
pub.send('polyglot');
},500);
The above code works as expected...but if I remove setInterval() and just call it like this:
var zmq = require('zmq');
var pub = zmq.socket('pub');
pub.bindSync('tcp://127.0.0.1:5555');
pub.send('polyglot'); //this message does not get delivered before exit
process.exit(0);
...Then the message will not get delivered - the program will apparently exit before the pub.send() call completes.
What is the best way to ensure a statement completes before exiting in Node.js ? Shutdown hooks would work here, but I am afraid that would just be masking the problem since you can't put everything that you need to ensure runs in a shutdown hook.
This problem can also be demonstrated this way:
if (typeof messageHandler[nameOfHandlerFunction] == 'function') {
reply.send('Success');
messageHandler[nameOfHandlerFunction](null, args);
} else {
reply.send('Failure'); //***this call might not complete before the error is thrown below.***
throw new Error('SmartConnect error: no handler for ZMQ message sent from Redis CSV uploader.');
}
I believe this is a legit/serious problem because a lot of programs just need to publish messages and then die, but how can we effectively ensure all messages get sent (though not necessarily received)?
EDIT:
One (potential) way to fix this is to do:
socket.send('xyz');
socket.close(); // supposedly this will block until the above message is sent
process.exit(0);
Diving into zeromq.node, you can see what Socket.send just pushes your data to _outgoing:
this._outgoing.push([msg, flags]);
... and then calls _flush iff zmq.ZMQ_SNDMORE is unset:
this._flush();
Looks like _flush is actually doing the socket write. If _flush() fails, it emits an error.
Edit:
I'm guessing calling pub.unbind() before exiting, will force the _flush() to be called:
pub.unbind('tcp://127.0.0.1:5555', function(err) {
if (err) console.log(err);
process.exit(0); // Probably not even needed
});
I think the simple answer is the the socket.send() method is in fact asynchronous and that is why we see the behavior I described in the OP.
The question then is - why does socket.send() have to be asynchronous - could there not be a blocking/synchronous version that we could use instead for the purpose intended in the OP? Could we please have socket.sendSync()?
I would ask about java script error, is there type of error like php
or others,
example: In php we have notice, and Parse Error ..etc notice will not
be stop php execute, but parse will be stop execute php code
directly..
now is there js error like this, or what is the js classification
error .. I know we can handle error by try, catch ..,but is there
error in js was stooped script and others will not stop execute script
thank you
is there error in js was stooped script and others will not stop execute script
Not except for parsing/syntax errors, no.
JavaScript has exceptions. An exception exits the code in which it is thrown, and the code that called that, and so on until it's caught. If it isn't caught, then all currently-running functions are terminated and the error is logged to the web console.
So an exception (either one you throw explicitly or one that happens as a by-product of something you do) will either terminate all running functions (if not caught) or only terminate some code (if caught).
For example:
function foo() {
try {
bar(0);
}
catch (e) {
console.log("Caught exception");
}
}
function bar(a) {
if (a <= 0) {
throw new Error("'a' cannot be <= 0");
}
console.log("bar: a = " + a);
}
foo();
There, the code in bar following the exception is not run (we don't see "bar: a = 0") because an exception was throw, terminating bar. But foo's code continues, in the catch block, because foo caught the exception.
JavaScript is unusual in that you can throw anything, including a string, a number, etc. But if you want useful information, you usually throw Error:
throw new Error("Optional message here");
Since what you throw can be anything, you might be thinking there's a way to catch only certain things, but that's not the case. catch catches any exception that was thrown. So:
try {
throw "foo";
}
catch (e) {
}
try {
throw new Error();
}
catch (e)
}
try {
throw 42;
}
catch (e)
}
Note that those catch clauses are identical; they catch anything that was thrown. Of course, you can then inspect what you got and re-throw:
try {
// ...some code here that may throw any of several things...
}
catch (e)
if (typeof e === "string") {
// Handle it here
}
else {
throw e;
}
}
There we only handle exceptions that are strings, and not ones that are numbers, Error objects, etc.
You can create your own derived versions of Error if you like, although it's a bit more of a pain than it ought to be:
function MySpecificError(msg) {
this.message = msg;
try {
throw new Error();
}
catch (e) {
this.stack = e.stack;
}
}
MySpecificError.prototype = Object.create(Error.prototype);
MySpecificError.prototype.constructor = MySpecificError;
Then:
throw new MySpecificError("Something went wrong.");
Note that we had to fill in the code in MySpecificError to create the stack trace. (Also note that not all engines provide a stack trace, but if they do, this lets you use it.)
Some engines provide a few error types out of the box:
Error
RangeError (something was out of range)
ReferenceError (but usually that's something you'd let the engine throw)
TypeError (again)
SyntaxError (again)
Finally, it's worth noting that several things that would cause exceptions in other environments don't in JavaScript, mostly around math. For instance:
var result = 10 / 0;
In many non-JavaScript environments, that results in a runtime error (division by zero). In JavaScript, it doesn't; result gets the value Infinity.
Similarly:
var x = Number("I am not a number");
or
var x = parseInt("I am not a number", 10);
...doesn't throw a parsing error, it sets x to NaN ("not a number").
Yes. Javascript errors can have types, and there is a standard error type hierarchy. You can also write your code to "throw" things that are not error objects.
(In fact, since the catch clause in Javascript / ECMAScript does not discriminate based on the type of the exception, exception handling tends to be rather crude; i.e. "catch all errors" and then attempt to recover. Hence, to a first order, it doesn't matter what you throw.)
The ECMAScript 5.1 spec says that syntax errors are "early errors" and that they must be reported before the program is executed. An exception to this is syntax errors detected in code being run using eval. However, the spec doesn't say how early errors are to reported, or what happens afterwards. (At least, I don't think it does ...)
I believe that a common strategy for a Javascript parser/compiler/interpreter to skip to the enclosing block, and replace the affected code with code that throws an exception (e.g. SyntaxError) if it is run.
References:
http://www-archive.mozilla.org/js/language/js20-1999-02-18/error-recovery.html
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError
EcmaScript 5.1 - Errors
Is it possible to terminate script on a certain condition with a specific error message? Exceptions are not an option, as they can be catched, thus avoiding termination.
Update:
I'd prefer the universal approach, but if there's none, then it's for the in-browser JavaScript. Error should be silent, and the error message should only go into the browser error log.
If your code is inside a try statement, and you are looking for a way to stop it for certain errors, then I think you are looking for the finally block:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Statements?redirectlocale=en-US&redirectslug=JavaScript%2FGuide%2FStatements#The_finally_Block
From that site (and editing the annoying alert() for console.log()) you can find this example:
function f() {
try {
console.log(0);
throw "bogus";
} catch(e) {
console.log(1);
return true; // this return statement is suspended until finally block has completed
console.log(2); // not reachable
} finally {
console.log(3);
return false; // overwrites the previous "return"
console.log(4); // not reachable
}
// "return false" is executed now
console.log(5); // not reachable
}
f(); // alerts 0, 1, 3; returns false
Unfortunately, I only managed to accomplish this through the following ugly workaround:
var failWithFatalError; // A non-existent function
console.error (message + ' in ' + homebrewStackTraceFunction());
failWithFatalError();
I encountered quite annoying problem. I can't catch errors thrown from within the functions. And to be honest - I wouldn't care much if not the fact that the same applies for throwing errors from within the JavaScript Objects.
Here's the sample code:
http://jsfiddle.net/TxsHK/1/ (you'll need firebug console to test this code)
function ViewError($CONTENT){
this.content = $CONTENT;
return this.content;
};
try{
$(document).ready(function() {
//--------------
throw ViewError('Test error');
//--------------
});//$(document).ready(function() {
}catch (e) {
if (e instanceof ViewError) {
console.info(e.message);
}
else{
console.warn(e.message);
}
}
gives an error
TypeError: e is undefined
Why? The errors thrown by functions (or objects) should be perfectly catchable. That's the whole purpose of try - catch block: to catch exceptions out of functions. At least... so it is in other languages.
Anyone can explain what's going on? And how can I catch exceptions from within the functions / objects?
Your "ViewError" function doesn't return anything. You're therefore throwing undefined. (edit — your fiddle is diffferent from the posted code - don't do that!)
The "ViewError" function is being called in a way that I don't think to be correct, given the way the code is written. I think you want throw new ViewError("Test error"); in order to make sure a new object is created.
There's another problem: you're expecting that you'll be able to catch exceptions thrown from that call to $(document).ready(), but that's not necessarily going to work. If the document isn't ready yet when that code runs, then you'll get no exceptions because the call returns immediately. The function you pass in would be called later, when the document is ready.
If I have a javascript error outside of a callback, Firebug console prints out the error. However, if I have ant error inside a callback, I will not see any printout.
document.observe('dom:loaded', function() {
// not notified in console
alert(undefinedVariable);
});
// notified in console
alert(anotherUndefinedVariable);
Almost all of my code is inside callbacks, so it is making it hard for me to track down errors. How do I print out every error in the console no matter where the error occurs?
I needed to tell Prototype to not swallow the exceptions.
Ajax.Responders.register({
onException: function(request, exception) {
(function() { throw exception; }).defer();
}
});
You can try printing to the console explicitly -- window.console.log(...something...) should work from anywhere.