Дизайн, управляемый доменом: dart package freezed дает «Логическое выражение Failed Assertion не должно быть нулевым»

Я пытаюсь создать модель электронной почты с аутентификацией, используя этот учебник https://www.youtube.com/watch?v=fdUwW0GgcS8&list=PLB6lc7nQ1n4iS5p-IezFFgqP6YvAJy84U&index=2

Код такой:

      import 'package:flutter/cupertino.dart';
import 'package:dartz/dartz.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:flutter/foundation.dart';

part 'email_address.freezed.dart';

//https://www.youtube.com/watch?v=fdUwW0GgcS8&list=PLB6lc7nQ1n4iS5p-IezFFgqP6YvAJy84U&index=2

// Make Illegal states unrepresentable

@immutable
class EmailAddress {
  final Either<ValueFailure<String>, String> value;

  factory EmailAddress(String input) {
    //assert input is not null
    assert(input != null);

    //use private constructor
    return EmailAddress._(
      validateEmailAddress(input),
    );
  }

  // private constructor which will be used in factory constructor if email is valid.
  const EmailAddress._(this.value);

  @override
  String toString() {
    return 'EmailAddress($value)';
  }

  @override
  bool operator ==(Object o) {
    if (identical(this, o)) return true;

    return o is EmailAddress && o.value == value;
  }

  @override
  int get hashCode => value.hashCode;
}

// Use a REGEX expression to valid the email address.
Either<ValueFailure<String>, String> validateEmailAddress(String input) {
  const emailRegex =
      r"""^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+""";
  if (RegExp(emailRegex).hasMatch(input)) {
    // right side of Either gives String of valid email
    return right(input);
  } else {
    // left side of either gives ValueFailure<String>
    return left(ValueFailure.invalidEmail(failedValue: input));
  }
}

@freezed
abstract class ValueFailure<T> with _$ValueFailure<T> {
  const factory ValueFailure.invalidEmail({
    @required String failedValue,
  }) = InvalidEmail<T>;
  const factory ValueFailure.shortPassword({
    @required String failedValue,
  }) = ShortPassword<T>;
}

Однако у меня возникает ряд проблем с правильной работой замороженного пакета.

Сначала получалось сообщение о конфликте версий между SDK и анализатором:

      Your current `analyzer` version may not fully support your current SDK version.

Please try upgrading to the latest `analyzer` by running `flutter packages upgrade`.

Analyzer language version: 2.10.0
SDK language version: 2.12.0

Я добавил следующее в pub spec.yaml, который, похоже, исправил это:

      dependency_overrides:
  analyzer: ^0.41.1

Однако теперь я получаю сообщение об ошибке ниже при запуске flutter pub run build_runner watch,

      [INFO] 7.8s elapsed, 3/4 actions completed.
[SEVERE] freezed:freezed on lib/domain/auth/email_address.dart:

Failed assertion: boolean expression must not be null
[INFO] Running build completed, took 8.1s.

Я пробовал добавить

      analyzer:
  enable-experiment:
    - non-nullable

в analysis_options.yaml на основе некоторых поисковых запросов, но все еще получаю ошибку.

Любая помощь приветствуется!

2 ответа

Это сработало для меня. Благодарим Питера Томпсона за это решение (находится в разделе комментариев к руководству)

  1. отредактируйте значение sdk в спецификации pub, чтобы включить нулевую безопасность звука:
          environment:
      sdk: ">=2.12.0 <3.0.0"
  1. Используйте фиксированные и фиксированные аннотации версии 0.14.2 (или более поздней):
          dependencies:
      flutter:
        sdk: flutter
      dartz: ^0.9.0-dev.6
      freezed_annotation: ^0.14.2
    
    dev_dependencies:
      build_runner:
      freezed: ^0.14.2
  1. Добавить "?" после объявления типа для failedValue:
          @freezed
    abstract class ValueFailure<T> with _$ValueFailure<T> {
      const factory ValueFailure.invalidEmail({
        @required T? failedValue,
      }) = InvalidEmail<T>;
      const factory ValueFailure.shortPassword({
        @required T? failedValue,
      }) = ShortPassword<T>;
    }

Я пробовал ваш код, и решение состояло в том, чтобы установить конкретную версию freezed в pubspec.yaml:

      dependencies:
  freezed_annotation: ^0.12.0
dev_dependencies:
  freezed: ^0.12.2

Нет необходимости отменять analyzer версия пакета.

Это работает с Flutter 2.0.3 и Dart 2.12.2.

Другие вопросы по тегам