Skip to content

v2.0.0

Choose a tag to compare

@JonathanPeterCole JonathanPeterCole released this 08 May 17:01
· 2 commits to main since this release

This release aims to make it easier to implement custom Cancellables and provide more useful information for debugging.

  • Added a .cancelWithReason() method to CancellationToken for a convenient way to set provide a cancellation reason for debugging.
  • CancelledException now overrides .toString() to give a more useful message for debugging, including the cancellation reason.
  • Cancellation stack traces now show the call stack leading up to the operation that was cancelled, rather than the call stack leading up to the token's cancellation. This should make it easier to identify the origin of uncaught cancellation exceptions.
  • Added a .detach() method to the Cancellable mixin. When paired with .maybeAttach(), this will detach your cancellable from the token.
  • Fixed a bug where the ignoreCancellation() wouldn't call whenComplete if onError threw an exception.
  • Fixed a bug where asCancellable() could result in uncaught exceptions.

Breaking changes

These changes are isolated to projects using custom cancellables or cancellation tokens. Other projects are unaffected.

  • The CancellationToken.attach() and .detach() methods have been renamed to .attachCancellable() and .detachCancellable().
  • The CancellationToken.exception getter now returns null if the token hasn't been cancelled yet.
  • The CancellationToken.cancel() method's exception parameter is now nullable, rather than using a default value.
  • Removed the [StackTrace? stackTrace] parameter from the Cancellable mixin's onCancel method. Instead, use the new cancellationStackTrace, which returns the stack trace at the time the cancellable was created.
  • Overridden Cancellable mixin methods must now call super.

To migrate your custom cancellation tokens:

  • If you're overriding the .attach() and .detach() methods, rename them to .attachCancellable() and .detachCancellable().
  • If you're overriding .exception, update it to be nullable and only return an exception if the token's been cancelled.
  • If you're overriding .cancel(), update it to make the exception parameter nullable. If you were previously setting a default value, consider setting this within the method instead:
    @override
    void cancel([Exception? exception]) {
      exception ??= YourCustomDefaultException();
      super.cancel(exception);
    }

To migrate your custom cancellables:

  • Replace calls to cancellationToken.attach(this) with maybeAttach(cancellationToken).
  • Replace calls to cancellationToken.detach(this) with detach().
  • Update onCancel() overrides to call super.onCancel() and remove the stackTrace parameter. To get the stack trace, use cancellationStackTrace instead:
    // Old
    @override
    void onCancel(Exception cancelException, [StackTrace? stackTrace]) {
      _internalCompleter.completeError(
        cancelException,
        stackTrace ?? StackTrace.current,
      );
    }
    
    // New
    @override
    void onCancel(Exception cancelException) {
      super.onCancel(cancelException);
      _internalCompleter.completeError(cancelException, cancellationStackTrace);
    }