CancelledError
Standard library class · Extends Error
A CancelledError is what is raised inside a task that has been asked to stop, at the next place the task
waits. It is also what result() raises when asked for the result of a task that was
cancelled. It is how a cancelled task unwinds: it runs its cleanup and ends.
Tasks.run { tasks => const sleeper = tasks.start { => Program.sleep(Duration(seconds: 5)) } sleeper.cancel() try { sleeper.result() } catch error: CancelledError { print(error.message) }}this task was cancelledA CancelledError extends Error directly, not RuntimeError.
That is deliberate: a program’s catch error: RuntimeError, written to handle something that went wrong,
doesn’t swallow a cancellation. A task that catches every error with a plain catch error should raise
the error again, since swallowing a cancellation would leave a task that was meant to stop running on.
What happened, in words.
Cleanup always runs
Section titled “Cleanup always runs”A finally block runs when a task is cancelled, and it is protected from cancellation, even when the
cleanup itself has to wait. Closing a file, releasing something, or telling another task can be done there
and will always complete. See the example under Task.cancel.
A cancelled group cancels and finishes its inner groups before its own cleanup ends, and a program that
calls exit() cancels and waits for its running tasks first.
What can be cancelled
Section titled “What can be cancelled”A task is cancelled at the next place it waits for something: Program.sleep, a channel’s send or
receive, another task’s result, a web request, or a wait for input. Files are the exception: a file
operation finishes first, and the cancellation arrives right after. That is nearly always immediate, but
a file that is really a slow device can delay it. A task that only calculates, and never waits, can’t be
cancelled until it does; calling Tasks.yield in a long loop gives it a place.