views:

69

answers:

4

One thing that is driving me nuts is how Javascript fails silently in many different situations.

(removed example because it confuses the point of my question)

Many times I have come across an error that will give an error message when typed into the Firebug console, but when it runs within the page script, it fails silently, even with the Firebug console active and open!

Some of these problems can be caught by Crockford's JsLint, but still many won't.

Isn't there a way to enable more error messages in the browser?

Can you do this at all without using javascript debugger environments? I find debuggers don't help me much. I usually sprinkle a few console.log() statements and can locate the problem in a minute. What drive me nuts is that silent errors in Javascript can go unnoticed for a long time, or show up in ways that are not obvious at all. It's even more frustrating because testing the statement in the console DOES give an error, so what's going on?

I have had the same problem with exceptions by the way, did anyone notice this? Often times my throw new statements don't work at all. But if I type the same thing in the console, it does.

Thanks for your helpful comments (first answers), but that is not my question. These tests are useful when you need to sanitize parameters to a class for example, when you don't know for sure about the environment. You don't want to test for existence of properties or classes where you expect them to be there; that would be bloating the code for no reason.

+3  A: 

If you are working with objects for which you are not sure if they exist at runtime or not, you have to check for their existence:

if (Foo && Foo.Apple) {
    // exists, do something with it
} else {
    // doesn't exist, do Plan B
}

Note that the expression (Foo && Foo.Apple) will first check if Foo exists, and only if it does, it will check if it has a property named Apple. If it has, the if-branch will execute.

If Foo does not exist, or if it does not contain the Apple property, the else-branch will execute.

Šime Vidas
You're right, but this particular issue was that I had one component in my javascript "bundle" that was not loaded. The code is not expecting that component not to be there, it's a dependency. My question is more about finding a way to get a notice instead of a silent error which is so frustrating at times.
faB
Well, if you have multiple components, you have to take the defensive stance and consider the possibility that one component may fail to load/execute. Of course, you expect it do be there, but you cannot be sure. That's why you program defensively and always first check if the particular component exists by using the if statement. If it exists, fine, if not, use the else-branch as a "notice". Of course, you can make use of the else-branch to try to load the component again (for example).
Šime Vidas
+3  A: 

The code below will catch all errors in catch block:

var a;
try {
    a = new Foo.Apple();
} catch (err) {
    // Error handling
}

For more info: http://www.w3schools.com/js/js_try_catch.asp

matte
-1 for declaring a variable inside of a block. Variable declaration statements should be the first statements of the execution context. Declaring variables "in the middle of the program" is a bad practice.
Šime Vidas
Also, I believe that defensive existence checking is a far better practice than forcing errors.
Šime Vidas
You're right about the variable declaration, fixed it in the comment. About the existence checking, if you need to specifically know which declaration failed, you are right, but in cases where it doesn't matter and there are lots of checks, this is much better I think.
matte
I reversed the -1, since you fixed it. However, in cases where there are lots of checks, you cannot tell which check failed based on the caught error object, anyway. If you call multiple constructors and one of them is not defined, you cannot tell which one failed based on the TypeError that you catch.
Šime Vidas
Thanks. My point is that if you don't need to know which one is failed (if you call multiple constructors), there is no need for all that if/else blocks, they will just clutter the source.
matte
Of course you want to know which constructor failed! Because you need that constructor, ergo, its functionality. The logic is this: 1. You need a certain constructor in order to do accomplish some functionality. 2. You check if that constructor exists. If it exists, you use it. If it doesn't exist, you run some ALTERNATIVE CODE which a) creates such a constructor or b) achieves the same functionality some other way. This is to ensure that "the job gets done" either way. This is why we use if-else.
Šime Vidas
In your solution, if the constructor does not exist, you just "call of the whole operation". Inside the catch block you are not able to fix the problem.
Šime Vidas
There are some cases that doesn't matter which constructor is failed. You need to simply run a block of code and fail silently if there are any errors. An example for that case; your classes/objects are constructed by a factory method on runtime and they are not features but addons. If they don't exist, fail silently. Another example, you need to write a quick implementation example for different classes/objects/functions/methods, put them all in try block. To know or not to know which constructor failed is up to the developer. It is not an 'of course' situation. Also, ...
matte
... now I realise that we are off the topic. The question is "Any way to stop Javascript from failing silently?", not how to fail silently. My misunderstanding.
matte
Yes. Sorry if the example was misleading. Yes this is good practice, but not the substance of my question. My question isn't about these good practices. I'm just trying to get such basic errors as trying to do something with an undefined function for example, to display an error in the console (whichever, Firebug, Opera's, Safari's).
faB
+2  A: 

Agree with @sime Vidas, if the exception has to be handled and not left silent, first use the boolean condition and check if the value exists.

if(Foo.Apple){
\\your code
}
else
{
//Foo.Apple does not exist, do some exception handling here
}
omniprasan
+1  A: 

I think some of the answers to this question are misinterpreting the question. IIUC, the question is saying that the error is being squelched when this code is run inside a real webpage, but the OP doesn't want it to be. (Presumably for debugging purposes, mainly.)

My question would then be, where is this code really running in the context of the website? Chances are something else is squelching the error before it gets to you. For instance, some libraries might instinctively squelch errors that occur within specific callbacks (e.g. for XHR). However, if they're good, they also tend to provide a hook point for receiving notification if an error occurred.

Ken
You're right. Now that you mention it, I think I saw sometimes errors caught by YUI (YUI 2.8). Maybe they're running a lot of code in try catch blocks? I'll test running my code in a try catch block to see what happens.
faB