Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

There is a provision for try-catch block in javascript. While in java or any other language it is mandatory to have error handling, I don't see anybody using them in javascript for greater extent. Isn't it a good practice or just we don't need them in javascript?

share|improve this question
add comment

4 Answers

up vote 17 down vote accepted

One should avoid throw errors as the way to pass error conditions around in applications.

The throw statement should only be used "For this should never happen, crash and burn. Do not recover elegantly in any way"

try catch however is used in situation where host objects or ECMAScript may throw errors.

Example:

var json
try {
    json = JSON.parse(input)
} catch (e) {
    // invalid json input, set to null
    json = null
}

Recommendations in the node.js community is that you pass errors around in callbacks (Because errors only occur for asynchronous operations) as the first argument

fs.readFile(uri, function (err, fileData) {
    if (err) {
        // handle
        // A. give the error to someone else
        return callback(err)
        // B. recover logic
        return recoverElegantly(err)
        // C. Crash and burn
        throw err
    }
    // success case, handle nicely
})

There are also other issues like try / catch is really expensive and it's ugly and it simply doesn't work with asynchronous operations.

So since synchronous operations should not throw an error and it doesn't work with asynchronous operations, no-one uses try catch except for errors thrown by host objects or ECMAScript

share|improve this answer
    
I wouldn't go so far as to say no one uses try catch, it's just the wrong tool for the job in most cases. When there are truly exceptional circumstances, it can be worthwhile to throw an Error, but they are few and far between. –  zzzzBov Apr 13 '12 at 16:56
3  
@zzzzBov There's nothing wrong with throwing errors for case C, crash and burn. I just don't think you should catch errors and recover. For example document.getElementById doesn't throw when the element doesn't exist, it just returns null. The same can done for almost all cases –  Raynos Apr 13 '12 at 17:07
3  
@Raynos, throwing from a sync function is totally acceptable and makes sense in that use case. Returning error to callback is to async as throwing error is to sync. –  sbartell Oct 3 '12 at 20:03
    
@Raynos have any good advice on avoiding using Errors/Exceptions for flow control on the client-side (non-Node environment)? I've found this post on StackOverflow, but it's mostly geared towards Java –  b.long Apr 18 '13 at 21:18
    
@b.long simple. don't throw errors ever. Problem solved. –  Raynos Apr 18 '13 at 22:16
show 5 more comments

Possibly another reason try/catch is not used very much in Javascript is the construct wasn't available in the very first versions of Javascript ...it was added later.

As a result, some older browsers don't support it. (In fact, it may cause a parser/syntax error in some older browsers, something that's more difficult to "program defensively" against than most other types of errors.)

More importantly, since it wasn't available initially, the Javascript builtin functions that were initially released (what one would call the "library" functions in many languages) don't make use of it. (It doesn't work very well to "catch" an error from someobject.somefunction() if it doesn't "throw" but instead just returns "null" when it encounters a problem.)


Yet another possible reason is the try/catch mechanism didn't seem to be necessary initially (and still doesn't seem all that useful). It's really needed only when calls are routinely nested several levels deep; just returning some sort of ERRNO would work fine for direct calls (although to make it really useful whenever it's available, best practice in most languages is to use it everywhere rather than just on deeply nested calls). As Javascript logic was originally expected to be small and simple (after all, it's just an adjunct to a webpage:-), function calls weren't expected to be deeply nested, and so a try/catch mechanism didn't seem necessary.

share|improve this answer
add comment

I believe that much of the reason that try..catch is rare in JavaScript is because the language has a pretty high tolerance for error. The vast majority of situations can be handled by using code checks, good defaults, and asynchronous events. In some cases, simply using a pattern will prevent issues:

function Foo() {
    //this may or may not be called as a constructor!!
    //could accidentally overwrite properties on window
}

function Bar() {
    if (!(this instanceof Bar)) {
        return new Bar();
    }
    //this will only work on Bar objects, and wont impact window
}

Some of the major issues in other languages that cause exceptions to occur simply don't exist in JS. Type casting isn't needed the vast majority of the time. Instead, the preferred method is typically to feature check (enforcing a particular interface):

function doFoo(arg) {
    if (arg.foo) {
        arg.foo();
    } else {
        Bar.prototype.foo.call(arg);
    }
}
share|improve this answer
add comment

Try/catch in Javascript is not as bullet-proof as in other languages, due to Javascript's asynchronous nature. Consider this snippet:

try {
    setTimeout(function() {
        do_something_that_throws();
    }, 1000);
}
catch (e) {
    alert("You won't see this!");
}

The problem is that the control flow leaves the try block before do_something_that_throws() gets executed, so the error thrown inside the callback never gets catched.

So try/catch is basically inappropriate in many cases, and it's not always obvious whether something executes code asynchronously or not. Fortunately, javascript with its peculiar single-threaded-asynchronous-callback idiom and its support for actual closures provides an elegant alternative: continuation-passing style error handling. Just pass the proper response to any error as a function, e.g.:

setTimeout(function () {
    do_something_that_calls_err(function(err) {
        alert("Something went wrong, namely this: " + err);
    }),
    1000);
share|improve this answer
2  
it's not bullet proof in other languages either. Port that code to any language that supports asynchronous callbacks and it will fail too. –  Raynos Apr 13 '12 at 22:23
    
@Raynos: You are right; however, other languages (or rather, their supporting cultures) do not buy this heavily into the asynchronous-callback idiom as Javascript does, and due to the multi-threaded nature of most other environments, the shortcomings of try/catch are more obvious and surrounded by lots of other caveats, so people naturally tread carefully in multi-threaded/asynchronous callback situations, and are more aware of potential pitfalls. –  tdammers Apr 15 '12 at 12:21
    
Is this really due to JavaScript's "asynchronous nature?" As far as I can see, Try/Catch could theoretically be made to work lexically like how identifiers are lexically closed; it just doesn't happen to work that way in JavaScript. –  Brian Gordon Dec 3 '12 at 10:00
1  
In node.js >= 0.8 it is worth noting it is possible to try/catch asynchronously, please see my question stackoverflow.com/questions/14301839/… –  Benjamin Gruenbaum Feb 1 '13 at 3:41
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.