37

const is a block level variable so when i try suspect code

try{
   const foo = bar[global.name].foofoo[global.name2];
}catch (err){
    console.log(error(err.message));
}

const is hide in the {}

but

const foo ;
try{
    foo = bar[global.name].foofoo[global.name2];
}catch (err){
    console.log(error(err.message));
}

not working either because const must be init on declaration.
So how should I using const in try..catch block ?

pery mimon
  • 7,713
  • 6
  • 52
  • 57
  • 9
    `const foo = (() => { try { return ...} catch(e) { return defaultValue})()` – Yury Tarabanko Mar 29 '17 at 10:18
  • 1
    In this case you can declare a variable with `let` rather than `const`, outside of your try/catch block – ttarik Mar 29 '17 at 10:18
  • Please show us what you were trying to do with `foo` and where - if you don't need it, the solution is to omit it – Bergi Mar 29 '17 at 10:31
  • This is a fundamental question. for sure I have other solution to make code work. but I wonder what Ecma thinks when they implement/design this – pery mimon Mar 29 '17 at 13:03
  • 1
    They think that when you declare `const` inside a block, you will only use it inside that block. If you wanted to use it outside of the block, that would raise the question what its value would be if the block is not executed (e.g. when an exception happens and only the `catch` block is executed). If you cannot answer that question, `const` is not what you want. – Bergi Mar 29 '17 at 19:13
  • See my answer here: https://stackoverflow.com/a/50870635/476951 – yunzen Jun 15 '18 at 07:05

1 Answers1

42

You've hit the nail on the head, because of block scoping you can't declare a const in a try catch block and use it outside the block.

You have 2 3 options:

Use let:

let foo;
try{
    foo = bar[global.name].foofoo[global.name2];
}catch (err){
    console.log(error(err.message));
}

Or if there is very little code to come after the try catch block, and it all depends on the success of the try, you can put the rest of the code in the try:

try{
    const foo = bar[global.name].foofoo[global.name2];
    return foo;
}catch (err){
    console.log(error(err.message));
}

EDIT

Option 3 inspired by @Yury Tarabanko's comment: if possible modularise the try catch part into its own function, the output of which should be the value of the new const:

function trycatch() {
    try {
        return bar[global.name].foofoo[global.name2];
    } catch (err) {
        console.log(error(err.message));
        return undefined; // or whatever you want
    }
}

const foo = trycatch(); // === bar[global.name]... if succeeded, otherwise === the return value from the catch block
Aron
  • 8,696
  • 6
  • 33
  • 59
  • 1
    There is option #4 based on #1 described here: https://stackoverflow.com/a/50870635/476951 – yunzen Jun 15 '18 at 07:04
  • 2
    I like option 3, but it cannot be used if you must stop the initial function in the catch. – Félix Brunet Jul 10 '18 at 13:52
  • 1
    I came here looking for better solutions, but I guess there aren't any. Currently using your first solution, except assigning the `let` value to a `const` after the block. Unfortunately, I can't delete the temporary variable to let the runtime know it can optimise it away, as far as I know. – Adam Barnes Sep 05 '19 at 01:06
  • There's an alternative to option 3 here which I think is an improvement: https://stackoverflow.com/questions/40925094/javascript-set-const-variable-inside-of-a-try-block/50870635#answer-65209114 – s6mike Jan 07 '23 at 23:54