Is try {} without catch {} possible in JavaScript?

118,782

Solution 1

No. You have to keep them.

This actually makes sense since errors shouldn't be silently ignored at all.

Solution 2

A try without a catch clause sends its error to the next higher catch, or the window, if there is no catch defined within that try.

If you do not have a catch, a try expression requires a finally clause.

try {
    // whatever;
} finally {
    // always runs
}

Solution 3

It's possible to have an empty catch block, without an error variable, starting with ES2019. This is called optional catch binding and was implemented in V8 v6.6, released in June 2018. The feature has been available since Node 10, Chrome 66, Firefox 58, Opera 53 and Safari 11.1.

The syntax is shown below:

try {
  throw new Error("This won't show anything");
} catch { };

You still need a catch block, but it can be empty and you don't need to pass any variable. If you don't want a catch block at all, you can use the try/finally, but note that it won't swallow errors as an empty catch does.

try {
  throw new Error("This WILL get logged");
} finally {
  console.log("This syntax does not swallow errors");
}

Solution 4

Nope, catch (or finally) is try's friend and always there as part of try/catch.

However, it is perfectly valid to have them empty, like in your example.

In the comments in your example code (If func1 throws error, try func2), it would seem that what you really want to do is call the next function inside of the catch block of the previous.

Solution 5

I wouldn't recommend try-finally without the catch, because if both the try block and finally block throw errors, the error thrown in the finally clause gets bubbled up and the try block's error is ignored, in my own test:

try {
  console.log('about to error, guys!');
  throw new Error('eat me!');
} finally {
  console.log ('finally, who cares');
  throw new Error('finally error');
}

Result:

>     about to error, guys!
>     finally, who cares
>     .../error.js:9
>         throw new Error('finally error');
>         ^
>     
>     Error: finally error
Share:
118,782

Related videos on Youtube

pimvdb
Author by

pimvdb

Updated on March 01, 2022

Comments

  • pimvdb
    pimvdb over 2 years

    I have a number of functions which either return something or throw an error. In a main function, I call each of these, and would like to return the value returned by each function, or go on to the second function if the first functions throws an error.

    So basically what I currently have is:

    function testAll() {
        try { return func1(); } catch(e) {}
        try { return func2(); } catch(e) {} // If func1 throws error, try func2
        try { return func3(); } catch(e) {} // If func2 throws error, try func3
    }
    

    But actually I'd like to only try to return it (i.e. if it doesn't throw an error). I do not need the catch block. However, code like try {} fails because it is missing an (unused) catch {} block.

    I put an example on jsFiddle.

    So, is there any way to have those catch blocks removed whilst achieving the same effect?

  • pimvdb
    pimvdb about 13 years
    You're correct. However if code like try {...}; try {...} would be possible, the meaning of the code might be clearer (try the first, otherwise try the second).
  • pimvdb
    pimvdb about 13 years
    About your edit: In the JSFiddle example, the second function returns something, so is the third function really evaluated in that case? I thought a return statement stops anything coming after it.
  • user3167101
    user3167101 about 13 years
    @pimvdb Sorry, I didn't check the fiddle. return will cause the function to return prematurely. I will update my answer.
  • pimvdb
    pimvdb about 13 years
    Why I'm using this currently is because I have several algorithms to determine the best move in a game. Sometimes, the tactic of func1 has no best moves, so I'd like to move on to the second tactic tried in func2. Could you please tell me why this would be unadvisable?
  • ThiefMaster
    ThiefMaster about 13 years
    In that case those functions should not throw errors but return e.g. null and you do something like return func1() || func2() || func3();
  • Gautam Dev
    Gautam Dev over 10 years
    This answer is factually incorrect, you can have try {}; finally {} as shown in stackoverflow.com/a/5764505/68210
  • Gautam Dev
    Gautam Dev over 10 years
    This answer is factually incorrect, you can have try {}; finally {} as shown in stackoverflow.com/a/5764505/68210
  • Gautam Dev
    Gautam Dev over 10 years
    This answer is factually incorrect, you can have try {}; finally {} as shown in stackoverflow.com/a/5764505/68210
  • ThiefMaster
    ThiefMaster over 10 years
    @DanielXMoore: But that's not really the point of the question.
  • user3167101
    user3167101 over 10 years
    @DanielXMoore Sure, it is, but finally{} is basically in the same spirit as catch{}. I'll update the answer.
  • binki
    binki about 10 years
    @DanielXMoore, without the catch (e) {}, the exception thrown by func1() would prevent func2() from being tried.
  • binki
    binki about 10 years
    @pimvdb, if try {…}; try {…} were a legal syntax, I am quite sure it would/should behave identically to try {…} finally{}; try {…} finally{}, meaning that the exceptions are not caught. Generally, you should only catch expected exceptions (e.g., “found no ideal move”) so that “real” exceptional situations (e.g., “x is not a function”) don’t get silently eaten by your try {…} catch (e) {…} block. This is why the Mozilla internally has a non-standard syntax of try {…} catch (e if e instanceof TypeError) {…} and also why try can have finally {} with no catch.
  • user2284570
    user2284570 over 9 years
    So the best way would be to write something liketry { // whatever; } finally { try { // whatever; } finally { try { // whatever; } finally { try { // whatever; } finally { //always run}}}?
  • duffymo
    duffymo about 8 years
    Odd that mine was downvoted five years later when it says the same thing as other answers here. Mine appears to be the only one that was downvoted. Moderators, please take note.
  • Petr Peller
    Petr Peller about 8 years
    It sometimes makes perfect sense to have an empty catch, so I don't agree with your argument.
  • MKaama
    MKaama over 7 years
    Tcl has a very convenient single-word construct catch {my code}
  • ThaJay
    ThaJay over 7 years
    ever used JSON.parse? It throws on a parse error but I cannot depend on incoming information to always parse 100% of the time so it has to be like this: try {handleMessage( JSON.parse(message) )} catch (e) {} I think it would be nice if js had an auto-catch if omitted.
  • IncredibleHat
    IncredibleHat over 6 years
    @ThaJay exactly. As well, there are times where an object may or may not exist in a parent object (browser compatibility anyone?). Where its far easier to just try { some.buried.object.method(); } instead of doing a massive typeof .. != 'undefined' chain of if blocks.
  • Andrew Steitz
    Andrew Steitz over 5 years
    Above comment does not accurately answer OP because he doesn't want to run function 2 if function 1 succeeds.
  • chipit24
    chipit24 about 5 years
    No, catch is still required, it's just the binding that's not required...
  • Dan Dascalescu
    Dan Dascalescu about 5 years
  • Dan Dascalescu
    Dan Dascalescu about 5 years
  • Dan Dascalescu
    Dan Dascalescu about 5 years
  • duffymo
    duffymo about 5 years
    Why? Feels useless, unless it’s try/finally.
  • helsont
    helsont almost 5 years
    this answer is the most up to date! in terms of execution order, 1. it attempts the try block. 2. Catches the error. 3. Executes the finally block. 4. Throws the error. Is this correct?
  • Dan Dascalescu
    Dan Dascalescu almost 5 years
    Thanks @helsont. As for the execution order in the second code sample, I'm not sure one can tell whether the error is caught and re-thrown, or just (probably) simply thrown and not caught in the first place (since there's no catch). Surround the whole code with another try/catch and you'll be able to catch the This WILL get logged error.
  • Lenny
    Lenny almost 5 years
    Thank you that's what I needed :-) It would be really awesome if it also works without the try {} I mean: async () => { indicateWorkInProgress() await pipelineStep1() await pipelineStep2() ... finally { stopIndicator() } } It would be clear that the whole function is meant ;-) Those try blocks are so ugly there...
  • MrHIDEn
    MrHIDEn over 4 years
    @ThiefMaster there are some cases where errors are expected to be ignored silently. Where we expect we can fail and that is not a case to panic.
  • ICW
    ICW over 4 years
    This answer is factually incorrect and misleading. "It actually makes sense" you say, but you're wrong, it only makes sense in some cases and not others. It's a great example of a terrible answer being accepted inexplicably. There are many cases where it makes sense to have no catch block, like in an async function, sometimes. Being forced by the javascript language to create empty catch blocks is clearly pointless.
  • LeOn - Han Li
    LeOn - Han Li over 4 years
    Looks a lot clean now. Thanks for sharing!
  • Air
    Air over 3 years
    Just noticed this is nearly a decade old...Probably wasn't worth writing an answer.
  • Konrad Gałęzowski
    Konrad Gałęzowski about 3 years
    I would say you need to be sure that your finally block is simple enough to not throw any exception.
  • user
    user almost 3 years
    This helped me. Thank you.