Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

try/catch unnecessarily defines unused variable error #4088

Closed
benjie opened this issue Sep 9, 2015 · 4 comments
Closed

try/catch unnecessarily defines unused variable error #4088

benjie opened this issue Sep 9, 2015 · 4 comments

Comments

@benjie
Copy link

benjie commented Sep 9, 2015

The CS code

main = ->
  try
    throw new Error "Hello"
  catch e
    console.log e
  return

Compiles to:

// Generated by CoffeeScript 1.10.0
(function() {
  var main;

  main = function() {
    var e, error;
    try {
      throw new Error("Hello");
    } catch (error) {
      e = error;
      console.log(e);
    }
    return;
  };

}).call(this);

However catch (error) defines error within the scope of the catch block - defining it outside the scope of the catch block has no effect (and means there's a defined but unused variable which causes ESLint issues). This demonstrates that var error is not used:

function main() {
  var error = null;
  try {
    throw new Error("Hello");
  } catch (error) {
    console.log("Error 1", error);
  }
  console.log("Error 2", error);
}
main();

which results in:

Error 1 [Error: Hello]
Error 2 null

If I'm reading them right, section 12.14 of both v3 and v5 of the ECMA specs seem to imply that the catch block adds a new scope to the scope chain.

@vendethiel
Copy link
Collaborator

...Sadly, that last part isn't true on JScript, which is why CoffeeScript has this behavior. See #1476 / #2422 and a few duplicates.

@benjie
Copy link
Author

benjie commented Sep 9, 2015

@vendethiel I suspected JScript may be at fault here; however v1.9.3 didn't define the additional variable:

// Generated by CoffeeScript 1.9.3
(function() {
  var main;

  main = function() {
    var e;
    try {
      throw new Error("Hello");
    } catch (_error) {
      e = _error;
      console.log(e);
    }
    return console.log(e);
  };

}).call(this);

The only negative I can see to this approach is that on the faulty JScript it will define/clobber a global _error variable.

The v1.10.0 solution creates an ESLint error which, if disabled, will allow many more issues in a codebase to go undetected (defining a variable but never using it is often a sign that something's awry). Sadly the unused variable detection in CoffeeLint is not as powerful as that of ESLint so we tend to use both (we even wrote an ESLint formatter that reports the location of the issue honouring sourcemaps).

I think this particular solution to the issue needs revisiting.

@jashkenas
Copy link
Owner

Yes, it looks like a potential regression. I think the scoping was refactored a bit more recently.

@jashkenas jashkenas reopened this Sep 9, 2015
@vendethiel
Copy link
Collaborator

oh whoops, sorry again. I didn't look closely enough... my bad.

@lydell lydell closed this as completed in 75a4c01 Sep 10, 2015
jashkenas added a commit that referenced this issue Sep 10, 2015
Fix #4088: Don't declare caught variables
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants