Skip to content

@std/cli/unstable-progress-bar pipeTo promise is ignored #6472

Open
@nsf

Description

@nsf

The following code:

import { ProgressBar } from "@std/cli/unstable-progress-bar";

const pb1 = new ProgressBar(Deno.stdout.writable, { max: 5 });
pb1.add(5);
await pb1.end();
const pb2 = new ProgressBar(Deno.stdout.writable, { max: 5 });
pb2.add(5);
await pb2.end();

fails with:

[00:00] [##################################################] [0.00/0.00 KiB]
error: Top-level await promise never resolved
await pb2.end();
^
    at <anonymous> (file:///home/nsf/tmp/denotest/main.ts:8:1)

I think this is because returned pipeTo promise here:

stream.readable
.pipeTo(writable, { preventClose: this.#options.keepOpen })
.catch(() => clearInterval(this.#id));
is ignored and never awaited. Debugging shows "writer already locked" messages. I believe this is because internally pipeTo does getWriter() and releases the lock on close(), but you need to await for it.

The fix might look like so:

  1. Add #pipePromise: Promise<void>; member to the ProgressBar class.
  2. Store the pipeTo promise:
    this.#pipePromise = stream.readable
      .pipeTo(writable, { preventClose: this.#options.keepOpen })
      .catch(() => clearInterval(this.#id));
    
  3. Await for it in end():
    await this.#print()
      .then(() => this.#writer.write(this.#options.clear ? "\r\u001b[K" : "\n"))
      .then(() => this.#writer.close())
      .then(() => this.#pipePromise)
      .catch(() => {});
    

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions