Anthony said:
Thomas 'PointedEars' Lahn posted :
Maybe not guaranteed but it has generally been observed that a syntax
error in the contents of one script element (or in a resource imported
by a single script element) does not interfere with the successful
interpretation/compilation of syntax error free code in other script
elements (or imported by other script elements) within the same
document. Any cited examples where it did would be important, but in
their absence this seems excessively paranoid.
If there is no guarantee that a syntax error at any point will not have
a negative impact outside of the particular interpretation/compilation
process (or, given that there is no guarantee, this is being assumed to
be a pertinent issue) then eval-ing potential syntax erroring code could
only be employed once per document as there must be no guarantee of the
ongoing consequences in the event of the syntax error actually occurring
when tried.
I did some more reading after I posted that, actually, and
I was starting to come to that same line of thought, albeit
not with any real confidence. Thanks for the tip, I think
I'll avoid them entirely for the time being and use another
method for making sure my code isn't going to bomb.
As a Java developer, try/catch/throw/finally were staples
of my existence, and I naturally transitioned that. But,
as has been said many, many times here, Javascript is
not Java.
Go back 4-5 years in the archives and the general advice would have been
never to use try-catch outside of the known/controlled environment of an
intranet. But there eventually does come a point when newly introduced
features start to seem viable in the general web context.
Try/catch/finally have been part of the language specification since the
turn of the centaury (more than half of the total existence of
javascript) and it is extremely unlikely that any new JS engines will be
created without some form of sensible handling for the construct. So any
residual compatibility issue is really just in relation to very old web
browsers; mostly the forth generation of browsers and their antecedents.
(However, note that it has been suggested that IE 5 supported this
construct, but in reality JScript 5.0 did not include any support for -
finally -, and is very slightly off-standard in its support for
try-catch (though not in a way that would be problematic in normal
situations).)
On the other hand, javascript's try/catch construct is nearly totally
useless (non-practical) for various reasons. The first of which is the
way in which it must be used.
In Java (and other languages with good exception handling support) you
can be very specific about which exceptions you catch and handle (and so
will be letting any exception that cannot be handled propagate). While
in javascript you have no choice but catch every exception that is
thrown. That means that having caught your exception you then have to
work out if it was the exception you were planning to handle and if not
re-throw it.
That then introduces the second problem with javascript's try/catch,
which is identifying exceptions. There are some things that the
language's specification does allow you to determine from an - Error -
object, and in some cases that will include the necessary information
needed to identify the Error. One of (or a combination of) the Error's -
constructor - or - name - properties should allow for the identification
of the type of Error object, at least for the exceptions thrown as a
direct result of correct implementation of the language's specified
algorithms (which might broadly be categorised as "NativeErrors"). The
problem is that knowing that a caught exception is, for example, an
instance of "ReferenceError" does not really pin down which error it is
you are handling (unless the code in the - try - block is so restricted
that there is only one point where a "ReferenceError" could be thrown.
This comes to the question of the Error's - message - property. In
reality messages are usually fairly explicit about what exception has
been thrown (and often where), but not in any standardised way. The
specification for the message property says "The initial value of
Error.prototype.message is an implementation-defined string" and never
gets more specific than that. And as a result no two browsers can be
expected to produce the same message in association with the same
exception. Indeed, any single browser with a language configuration
option may not produce the same message given two differing language
configurations (they are, after all, messages to the programmer and
might reasonable be presented in the programmer's specified (possibly
native) language given a script engine author with an appreciation of
the role of language in human culture).
And if the specified - message - property is not going to help identify
individual Error objects then any implementation specific 'errorNumber',
'description', or other non-specified properties of the Error object are
going to be of even less use.
That is all just with language specified exceptions and the resulting
Error objects. Next we have the browser and the DOM both being likely to
throw exceptions in response to executing javascript code. The W3C DOM
defines a DOMException interface with a - code - property that could be
used to identify the type of an exception thrown by the DOM. Except that
in reality DOM implementations throw other exceptions, such as some
Opera 7 versions throwing a "NOT IMPLEMENTED" error when a particular
method was called (which the DOM specification asserted should not throw
an exception at all when called), and the W3C DOM specifications provide
no code number for "NOT IMPLEMENTED" (indeed they could not as the DOM
modules, as specified, are an 'all or nothing' game, regardless of the
reality of many browsers having 'good enough' but incomplete
implementations).
But then there is the browser itself, which can throw any exception it
likes ("out of memory", "too much recursion", "permission denied") and
no matter how many 'name', 'message', 'description', 'type' or 'number'
properties such Error objects may have you are going to have a hard time
identifying any of those. At best you would be looking at a trial and
error process of provoking possible exceptions in known browsers and
recoding their 'unique' characteristics and then writing code that test
for them. A process that is as incompliable as attempting to create a
comprehensive browser sniffing system based upon object inference.
So javascript's try/catch implies the need to catch all exceptions and
then identify the exception caught to see if it is an expectation that
can be handled, and re-throw those that cannot be handled. But the
ability to identify exceptions is so limited/problematic that you would
be hard pressed to find any single example of anyone actually coding
this. And indeed the mass of code that would then necessarily appear in
every - catch - block would be so obviously excessive as to tip anyone
off that any genuine exception handling in javascript was a nightmare to
attempt.
As a result what you usually see are empty (or pointless: 'alert('Some
sort of script coded f**k-up that you, as a user, can do nothing
sensible about has happened');') - catch - blocks, sometimes (but by no
means always) followed by some code to test for the consequences of the
caught and suppressed exception having been thrown (such as checking to
see an expected XML HTTP request object does exist after the attempt to
create it).
This style of try/catch use can be practical but its sensible
applications are very few and far between. Indeed it is characterised by
your usually only seeing a single statement being executed inside the -
try - block so the potential expectations thrown at that point are
extremely limited in range. So obviously any attempt to apply such a
style on a larger scale would virtually have every statement inside its
own - try - block, and result in the inverse of the nightmare of trying
to identify exceptions in order to handle them.
Thus, one web application I work on has well in excess of 100,000
statements in its client side code, is designed for use where the
browser(s) is(are) specified and so support try/catch/finally, yet in
all of that there are just 4 tiny try/catch blocks. A general strategy
of defensive programming, where potential exception throwing conditions
are test for up-front and so never provoked is the best strategy for
avoiding all of the issues with try/catch. Of course that is probably
easier to implement for those of us who were doing this 4-5 years ago
when any use of try-catch on the public Internet was pretty much out of
the question.
For completeness, there is still potential for using try/catch in
javascript, and particularly when designing large/complex systems (which
maybe is not such a good idea with javascript as a language to start
with, but anyway ...). It would be reasonable to design a system that
made heavy use of its own exceptions, while pretty much ignoring any
other exceptions. If you are creating and throwing your own custom
exceptions you can guarantee that those expectations do carry enough
information to allow for their easy identification, and so allow for the
sensible handling of those exceptions (but only those exceptions) when
they are thrown. I have never had a desire to do that myself, but if a
system was designed from day one to use such an internal exception
handling system it could be completely justified, effective and reliable
(and certainly in a browser restricted context).
Finally, there definitely is a down side to showing the use of try/catch
to novices in that they sometimes latch onto them as a universal
panacea, wrap everything they write in try/catch blocks and so suppress
all errors. This leaves their code 'error free', in one sense (the sense
of showing errors to the user) but it results in code that is virtually
impossible to maintain because if it is ever observed to be 'not
working' (which is not at all unexpected under the circumstances) then
it is virtually impossible to work out why.
So any discussion of indictors of bad code can validly mention the use
of try/catch because many specific patterns in its use are very
indicative of bad code.
Richard.