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

false positive: no-unreachable inside catch block when throwing value created outside scope of try #1303

Open
jsejcksn opened this issue Jul 29, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@jsejcksn
Copy link
Contributor

Lint Name

no-unreachable

Code Snippet

lint_fail_test.ts:

import { assert } from "jsr:@std/assert@^1.0.1/assert";
import { assertThrows } from "jsr:@std/assert@^1.0.1/throws";

Deno.test("lint", () => {
  const error = assertThrows(
    () => {
      const fooError = new Error("foo");
      try {
        throw fooError;
      } catch (cause) {
        assert(cause instanceof Error && cause.message === "foo");
     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        throw new Error("bar", { cause }); /*                    │
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                       │
        │                                                        │
        └─ error[no-unreachable]: This statement is unreachable ─┘ */
      }
    },
    Error,
    "bar",
  );

  assert(error.cause instanceof Error && error.cause.message === "foo");
});

Expected Result

Running deno lint lint_fail_test.ts exits with status code 0

Actual Result

Exits with status code 1 (see additional info below)

Additional Info

For comparison, here's the same test module except that the declaration of fooError is inside the try block:

lint_pass_test.ts:

import { assert } from "jsr:@std/assert@^1.0.1/assert";
import { assertThrows } from "jsr:@std/assert@^1.0.1/throws";

Deno.test("lint", () => {
  const error = assertThrows(
    () => {
      try {
        const fooError = new Error("foo");
        throw fooError;
      } catch (cause) {
        assert(cause instanceof Error && cause.message === "foo");
        throw new Error("bar", { cause });
      }
    },
    Error,
    "bar",
  );

  assert(error.cause instanceof Error && error.cause.message === "foo");
});

The module lint_pass_test.ts passes linting, and both test modules complete successfully using Deno's test runner. Here is terminal output for both modules:

% deno lint lint_pass_test.ts
Checked 1 file

% deno lint lint_fail_test.ts
error[no-unreachable]: This statement is unreachable
  --> /Users/deno/lint_fail_test.ts:11:9
   | 
11 |         assert(cause instanceof Error && cause.message === "foo");
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  docs: https://lint.deno.land/rules/no-unreachable


error[no-unreachable]: This statement is unreachable
  --> /Users/deno/lint_fail_test.ts:13:9
   | 
13 |         throw new Error("bar", { cause }); /*                    │
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  docs: https://lint.deno.land/rules/no-unreachable


Found 2 problems
Checked 1 file

% deno test *_test.ts
Check file:///Users/deno/lint_fail_test.ts
Check file:///Users/deno/lint_pass_test.ts
running 1 test from ./lint_fail_test.ts
lint ... ok (0ms)
running 1 test from ./lint_pass_test.ts
lint ... ok (0ms)

ok | 2 passed | 0 failed (10ms)

This was discovered in a CI failure here:

…and might be a regression. Ref:

Version

deno 1.45.4 (release, aarch64-apple-darwin)
v8 12.7.224.13
typescript 5.5.2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant