Skip to content

bug: finally block in async function indicates incorrect missing block coverage #229

Open

Description

@bcoe

Observed Behavior

The following code:

async function abc() {
  try {
    return 'abc';
  } finally {
    console.log('in finally');
  } // this is a covered line but uncovered branch
}

abc()

Ends up having the following coverage output:

{
          "functionName": "abc",
          "ranges": [
            {
              "startOffset": 0,
              "endOffset": 146,
              "count": 1
            },
            {
              "startOffset": 97,
              "endOffset": 145,
              "count": 0
            }
          ],
          "isBlockCoverage": true
        }
}

This indicates that the following characters were tracked as an uncovered block:

// this is a covered line but uncovered branch\n

Expected behavior

Coverage should be 100% in the above example.

Activity

  1. bcoe commented on Jun 19, 2020

    @bcoe
    OwnerAuthor

    I have created a tracking issue on v8 here:

    https://bugs.chromium.org/p/v8/issues/detail?id=10628

  2. added a commit that references this issue on Jul 9, 2020
  3. evocateur commented on Feb 3, 2021

    @evocateur

    I'm not sure if it's related, but I think I hit this? I happened to be on c8 v7.4.0 when I encountered the failure in CI, but it reproduces in v7.5.0 when run on node v12.20.1.

    The tests pass, it's just the mysterious coverage gap on an async function that fails in node v12. v14 is fine.

    dendrochronologist/cli@edd0aaf "fixes" it by ignoring the missed line. Not ideal, long-term.

    However, if I avoid using the async keyword, it passes again:

    diff --git a/src/api.ts b/src/api.ts
    index 99472c5..69c22ef 100644
    --- a/src/api.ts
    +++ b/src/api.ts
    @@ -9,7 +9,7 @@ interface RunOptions extends Partial<ParsedConfig> {
       logger?: MinimalLogger;
     }
     
    -export async function run({
    +export function run({
       logger = processLogger(),
       ...options
     }: RunOptions): Promise<Node> {
    @@ -22,8 +22,5 @@ export async function run({
       const arb = new Arborist({
         path: cwd,
       });
    -  const tree = await arb.loadVirtual().catch(() => arb.loadActual());
    -
    -  return tree;
    -  /* c8 ignore next */
    +  return arb.loadVirtual().catch(() => arb.loadActual());
     }

    I validated this locally with

    volta run --node 12 npm test
    
  4. evocateur commented on Feb 3, 2021

    @evocateur

    To be clear, the node v14 I was passing with is v14.15.4. Which tracks, given the release of the linked back-porting. I have literally no idea if it could (or should?) be back-ported to v12, though it seems like a good candidate if someone has bandwidth?

  5. bcoe commented on Feb 5, 2021

    @bcoe
    OwnerAuthor

    @evocateur there are some v8 bug fixes that have landed in v14/v15, that I don't think got backported to v12 unfortunately -- I'm pretty sure that v12 might be closed to extension at this point unfortunately.

  6. evocateur commented on Feb 6, 2021

    @evocateur

    @bcoe Perfectly fair! Especially considering it's going into maintenance mode in like, 2 months? So I'll probably drop v12 before I even finish this wee babby of a tool, lol.

  7. simlu commented on Mar 31, 2022

    @simlu

    Just ran into this one as well. Rough one to debug. Any update regarding a fix?

  8. milanholemans commented on Sep 15, 2022

    @milanholemans

    I'm encountering something similar. My finally block has a coverage of 26, while the keyword finally has no coverage.

    image

    I'm using 5 finally statements in the entire solution, 4 of them are working as expected, only this one has no coverage. I have no idea how this is possible.
    I can send you a link to the code so you can see the problem yourself.

    Update

    Noticed that if you remove the throw statement in the catch block, that the finally is hit. However the amount of hits seems wrong.

    image

  9. xolott commented on Oct 13, 2022

    @xolott

    I'm also getting the same issue with a finally block. But this is not an async function.

    image

    Everything is 100% covered but the branch reports a 96.15% coverage

    I just added an ignore comment for now
    image

  10. bcoe commented on Nov 3, 2022

    @bcoe
    OwnerAuthor

    @xolott would you be able to provide a minimal breaking example, this would help in investigating the underlying cause.

  11. archiehharris commented on Jun 14, 2024

    @archiehharris

    @bcoe I have run into a similar issue as reported by @xolott, where the generated output is showing the finally block as uncovered. If you are still interested in troubleshooting, here is a minimum example repro

    EDIT: Just noticed that if you change the handler to finish without returning then the finally block is marked as covered:
    await orchestrator.activate()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions