question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Boilerplate to catch an explicit stream cancellation feels unnecessary

See original GitHub issue

It’s a good deal of ceremony to set up an abortable stream, you have to make an abort controller, and pass its signal,

then when you trigger the abort you need to handle an error at point of iteration, which feels like it should be unnecessary given that it’s requested behavior.

In brief, I’d like to not have to write the catch block in:

(async () => {
    for await (const resp of stream) {
      this.processResponse(resp);
    }
  })().catch((e) => {
    // silently catch cancellations which shouldn't be errors
    if (!(e instanceof ConnectError && e.code === Code.Canceled)) {
      throw e;
    }
})

note that this error handling code is very far (in a different) from the abort invocation, which is in a different file that spawns the request, so it’s a lot of context to hold in one’s head and feels pretty disconnected.

Thanks again for the library, I can’t wait to see how it develops!

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
timostammcommented, Sep 13, 2022

Regarding your original comment, we can simplify the problem statement a bit:

async function main(longRunning: Promise<number>) {
  const result = await longRunning;
  console.log("done", result);
}

When this function runs, the interpreter steps through the code, and suspends until the promise longRunning is resolved, then it continues to the log statement. Under the hood, async/await is just syntactic sugar for promises, and lets you write asynchronous code like procedural code.

The problem is, promises do not have a concept of cancellation (they either resolve, which means await returns the promised value, or the reject, which means await throws an error). So when cancellation was added to the fetch API, it was done with AbortError. This follows the design of async/await in C# (whether it was intentional or by coincidence, I do not know). Unfortunately, ECMAScript lacks a few language features that make this design ergonomic to use, and (as far as I am aware) there is no widespread handling of AbortError as something to ignore in the JS frameworks out there.

We obviously cannot change the ECMAScript language with connect-web, and we are very hesitant to change the standard behavior of raising an error on cancellation. That is why usePromiseClient() raises an error instead of - for example - returning an object with distinct properties cancelled, error and message. It works out for most use cases, but you don’t have to use it. In fact, we encourage you to write your own client.

0reactions
dnscocommented, Sep 14, 2022

Thanks!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Bug Patterns - Error Prone
This catch block appears to be catching an explicitly declared InterruptedException as an Exception/Throwable and not handling the interruption separately.
Read more >
How do we implement exception handling around Command ...
I have created a simple .NET Core console application with this line to execute the Command try { rootCommand.Invoke(args) } catch { Console ......
Read more >
Reducing Data Binding Boilerplate With Kotlin | Stable Kernel
But that seems a bit unnecessary. After all, in many cases, every time that ... This removes the need for you to explicitly...
Read more >
The Hidden Roles of Boilerplate and Standard-Form Contracts
First, suppliers could use boilerplate language to make their contracts com plex so that consumers would find it difficult to compare contracts of...
Read more >
Boilerplate's False Dichotomy - Georgetown Law
When presented in that way, the answer seems clear. ... boilerplate from other, necessary terms of the transaction, in such a way as...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found