Javascript error checking

  • Thread starter Christopher Benson-Manica
  • Start date
C

Christopher Benson-Manica

All right, since my previous idea (calling functions through a
wrapper) was apparently so awful no one could suggest any
improvements, I'll try a different tack. My end goal is to make
detecting and reporting script errors easy and painless. This could
be accomplished easily if window.onerror were ubiquitous, but it is
not. My new idea is to hack together something superficially
resembling C's assert() macro, perhaps something like

function assert( expr_as_string, cond ) {
var result=eval( expr_as_string );
if( cond == null ) {
cond=true;
}
if( result != cond ) {
alert( 'Assertion failed: '+expr_as_string+'=='+result+', expected
'+cond );
return false;
}
return true;
}

which would be used like

assert( '5 != 3' ); // true
assert( '5*10 == 3' ); // false

Now obviously this is, again, probably unacceptably obfuscatory.
That's why I'm posting and hoping, desperately, for suggested
improvements and/or other ideas. Surely given the amount of script
that's out there someone has conceived a half-reasonable error checking
framework...
 
N

nikki

Surely given the amount of script
that's out there someone has conceived a half-reasonable error checking
framework...

Sure they have.
Firefox has Venkman and the javascript console, and MSIE has a windows
javascript debugger whose name I forget.

That (good testing using these tools) and try/catch and good coding
with checks (i.e. checking for object before using it) should handle
pretty much anything that comes up, really.

My 2 cents, of course.
 
B

Baconbutty

I would agree with nikki.

I have written an application running to some 1MB (60,000 lines) of
Javascript, with only object/property checking (and a single try catch
for file saving) , with no problems, so I struggle to see the uses of
an error checking framework. Could you give some examples of
applications you would use it in?
 
C

Christopher Benson-Manica

Baconbutty said:
I have written an application running to some 1MB (60,000 lines) of
Javascript, with only object/property checking (and a single try catch
for file saving) , with no problems, so I struggle to see the uses of
an error checking framework. Could you give some examples of
applications you would use it in?

So the 60,000 lines of script never, ever has unexpected bugs? I know
our script is written and tested by humans and occasionally bugs creep
in. If a Safari user encounters one of these bugs, how do you find
out about it? I'm really struggling to understand how you avoid ever
making a mistake in 60,000 lines of script.
 
L

Lee

Christopher Benson-Manica said:
All right, since my previous idea (calling functions through a
wrapper) was apparently so awful no one could suggest any
improvements, I'll try a different tack. My end goal is to make
detecting and reporting script errors easy and painless. This could
be accomplished easily if window.onerror were ubiquitous, but it is
not. My new idea is to hack together something superficially
resembling C's assert() macro, perhaps something like

An important feature of assert() is that it can be compiled
out of the code for production release. Also, your assert()
will only be useful when checking global variables, since
variable names local to the calling function

Why not just add reasonable error checking to the code where
appropriate?

function myLibraryFunction(id, size, shape) {
if(size<MIN_SIZE || size>MAX_SIZE || !validShape["SHAPE_"+shape]) {
alert(...)
return;
}
var ref=document.getElementById(id);
if(ref) {
} else {
alert("invalid id \""+id+"\" passed to myLibraryFunction");
}
...
}
 
L

Lee

Lee said:
Christopher Benson-Manica said:

An important feature of assert() is that it can be compiled
out of the code for production release. Also, your assert()
will only be useful when checking global variables, since
variable names local to the calling function

[continuing that truncated paragraph]

variable names local to the calling function won't be available
in the scope of the eval() expression.
 
R

rich

Baconbutty said:
I would agree with nikki.

I have written an application running to some 1MB (60,000 lines) of
Javascript, with only object/property checking (and a single try catch
for file saving) , with no problems, so I struggle to see the uses of
an error checking framework. Could you give some examples of
applications you would use it in?

Maybe it's just me but I've been spoiled by the debugger built-in to Perl.
Besides a basic syntax check, which usually causes problems somewhere in 60K
lines of code, you can also step through your script line by line and test
variables to make sure your program is doing what it's suppose to. Would be nice
to have a desktop tool for Javascript to test your scripts through and maybe
check for browser compatibility as a bonus.


Rich
 
C

Christopher Benson-Manica

Lee said:
An important feature of assert() is that it can be compiled
out of the code for production release. Also, your assert()
will only be useful when checking global variables, since
variable names local to the calling function

Ey-yi-yi... well, so much for THAT plan. I actually don't want it
compiled out for a production release - a bug is a bug, and if the
script on a page is broken our users (and us!) need to know.
Why not just add reasonable error checking to the code where
appropriate?

Well, it seems that there is indeed no other choice, but it sure takes
up a lot of space. Additionally, the error handling is not always the
same, depending the UA (no lectures please) and whether the CGI
application is on a production or test system.

I appreciate the help, however.
 
B

Baconbutty

So the 60,000 lines of script never, ever has unexpected bugs?making a mistake in 60,000 lines of script.

Sorry, I am probably not quite understanding the problem you are
seeking to solve, and as I am working alone I don't face the same
problems you may have of managing the inputs from several programmers:
so my example was unfair.

Don't get me wrong, during development there were plenty of bugs and
errors, usually to do with unexpected variable types (Javascript being
loosely typed) or bad logic, which I identified and corrected with the
brute force test and debug approach. .

In this, I tried to identify those functions which could cause damage
if they were the wrong data/or produced the wrong output, or which
relied on something external (e.g. initialising a component), and built
in specific tests, expectations and fall backs. It is here that I
would perhaps include error checking: i.e. mission critical functions.

But apart from that, once tested and debugged, there were relatively
few such functions, and the program in practice has usually failed me
only in very subtle ways to do with the logic of the program, which I
assumed no amount of error catching code could help with.
 
R

Robert

Christopher said:
My new idea is to hack together something superficially
resembling C's assert() macro, perhaps something like

function assert( expr_as_string, cond ) {
var result=eval( expr_as_string );
if( cond == null ) {
cond=true;
}
if( result != cond ) {
alert( 'Assertion failed: '+expr_as_string+'=='+result+', expected
'+cond );
return false;
}
return true;
}

which would be used like

assert( '5 != 3' ); // true
assert( '5*10 == 3' ); // false

I think what you are trying to accomplish is not bad.
Just like assert in Java it can also be useful in Javascript.
I find assert especially useful to check the pre-conditions of my methods.
I use a validate method myself at the start of a lot of methods to check
the argument types.
This will make the rest of my method body much simpler, because I do not
have to take into account all the ways someone could have called my method.

Anyway, what I do not understand is why you use a string argument for
assert and not something like:

Assert.assertEquals(5, 3, "error message");

Personally I use a Application.debug variable if I don't want to do any
validation for example for production environments. Although I usually
just keep it on, because it can produce some useful stacktraces for me.
 
C

Christopher Benson-Manica

Baconbutty said:
But apart from that, once tested and debugged, there were relatively
few such functions, and the program in practice has usually failed me
only in very subtle ways to do with the logic of the program, which I
assumed no amount of error catching code could help with.

I think the difference is that your 60K lines were a
write-it-and-leave-it deal, whereas the scripts I'm dealing with are
constantly being updated and revised to provide new functionality, and
for better or worse there are several quite complex framesets with
heavily interlocked and mostly undocumented script. All manner of
things have and will go wrong, and in addition there are always little
browser-specific gotchas to worry about. The window.onerror handling
we have now just five minutes ago caught a Firefox-specific script
error that a user encountered that we might not otherwise have known
about.
 
B

Baconbutty

whereas the scripts I'm dealing with are
You are right. I can see the problem you face. You need code to help
you make the best of the situation. Sorry I have not been able to
assist.
 
N

nikki

Christopher said:
I think the difference is that your 60K lines were a
write-it-and-leave-it deal, whereas the scripts I'm dealing with are
constantly being updated and revised to provide new functionality, and
for better or worse there are several quite complex framesets with
heavily interlocked and mostly undocumented script.

See, there's your problem right there.
Well-written code is both documented and encapsulated.
A function checks what it needs before using it. Since JS is not
strongly typed, check the argument types. Check for object existence
before using it. NO GLOBAL VARIABLES. And so on.
If you're writing things complex enough to look like java or C#, then
write it well like java or C#.
Smack other developers who make your life harder by not doing so. LOL
All manner of
things have and will go wrong, and in addition there are always little
browser-specific gotchas to worry about.

I have yet to encounter a browser specific gotcha that was not easily
noticed by good object detection.
For example, older versions of Opera supported document.getElementById,
but not dynamic styles.
So to make sure it didn't crash, you could do this:

var myElement;
if (document.getElementById)
{
myElement = document.getElementById("elementId");
if (myElement.style && myElement.style.visibility)
{
myElement.style.visibility = "hidden";
}
}

You could add "else"s in there to inform you/the users about lack of
support for a feature.

Most scripts you see posted don't get that detailed (just not worth the
time for small sites, you know?), but if you have a huge amount of
code, in order for it to be production quality, these types of checks
need to run through the whole thing.
Use of these sorts of checks, combined with try/catch, encapsulation,
documentation, and getters/setters (typical OOP methods that provide
stability and prevent variables from being set to values they shouldn't
be set to, etc) would negate the need for an elaborate assertion
system.
 
C

Christopher Benson-Manica

nikki said:
A function checks what it needs before using it. Since JS is not
strongly typed, check the argument types. Check for object existence
before using it. NO GLOBAL VARIABLES. And so on.

Right, but to be thorough one should really check everything, which
entails a significant performance hit when dealing with hundreds to
thousands of form fields.
If you're writing things complex enough to look like java or C#, then
write it well like java or C#.

It's a nice thought...
So to make sure it didn't crash, you could do this:

Right, but if we did that everywhere the code would be extremely
mangled (although in places the indentation does a great job of
mangling by itself), and we would also be serving perhaps several
extra K of data with every page, which would definitely add up.
Most scripts you see posted don't get that detailed (just not worth the
time for small sites, you know?), but if you have a huge amount of
code, in order for it to be production quality, these types of checks
need to run through the whole thing.

Well, there's certainly a ton of code, but it generally flies by the
seat of its pants, as it were. If something unexpected happens, the
best it can do is inform us, the developers, so we can try to track it
down and eliminate it.
Use of these sorts of checks, combined with try/catch, encapsulation,
documentation, and getters/setters (typical OOP methods that provide
stability and prevent variables from being set to values they shouldn't
be set to, etc) would negate the need for an elaborate assertion
system.

I suppose either one would require a substantial amount of work, as
well as buy-in from everyone else...
 
C

Christopher Benson-Manica

Robert said:
I think what you are trying to accomplish is not bad.

I'm glad someone thinks the concept is worth thinking about, even if
it actually isn't workable in practice.
I use a validate method myself at the start of a lot of methods to check
the argument types.

That may be something to move toward, but it just doesn't exist right
now.
 
C

Christopher Benson-Manica

nikki said:
That (good testing using these tools) and try/catch and good coding
with checks (i.e. checking for object before using it) should handle
pretty much anything that comes up, really.

Well, the point of this assert() idea was to start actually checking
types and existence of objects without being ridiculously verbose.
All that error checking and try/catch makes it that much more
difficult to get at the heart of what the script actually does, IMHO.
 
C

Charles Harrison Caudill

Christopher Benson-Manica said:
Now obviously this is, again, probably unacceptably obfuscatory.

javascript does pass-by-value for function pointers, ie it passes functions
not function pointers. you can also lambda stuff so:

assert(function(){var my = stuff + to + do; return var != null;}, true);

good luck lawn gnome,
Harrison
 
C

Charles Harrison Caudill

See, there's your problem right there.
Well-written code is both documented and encapsulated.

This might be a newbie response, but I have a couple of helper functions for
my CNN owned implementation of sprintf, and I had to preface them with a
sprintf_ in the name just so that I could do this encapsulation. Javascript
strikes me as the type of language that is *meant* to entice suicide in the
programmer, kindof like squeak.
A function checks what it needs before using it. Since JS is not
strongly typed, check the argument types. Check for object existence
before using it. NO GLOBAL VARIABLES. And so on.

That would be nice except that you don't have a main and you don't have static
variables inside of functions. How do you accomplish html templating stuff
without globals?
If you're writing things complex enough to look like java or C#, then
write it well like java or C#.

Here Here! If only there was a python-like client-side scripting language...
Smack other developers who make your life harder by not doing so. LOL

I'd hand you the glove.
I have yet to encounter a browser specific gotcha that was not easily
noticed by good object detection.

In opera, file dialog boxes will, upon myBox.value, return just the file name,
not the fully qualified path. First you have to do, myBox.type = "text";,
to get the fully qualified path. IE and firefox don't require that.
Most scripts you see posted don't get that detailed (just not worth the
time for small sites, you know?), but if you have a huge amount of
code, in order for it to be production quality, these types of checks
need to run through the whole thing.
Use of these sorts of checks, combined with try/catch, encapsulation,
documentation, and getters/setters (typical OOP methods that provide
stability and prevent variables from being set to values they shouldn't
be set to, etc) would negate the need for an elaborate assertion
system.

I'm with the lawn gnome here; I've gotten to the point where I'm developing a
set of javascript tools to deal with stuff like this, including debug.js.

-Harrison
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top