FlutterError.fromParts constructor Null safety

FlutterError.fromParts(
  1. List<DiagnosticsNode> diagnostics
)

Create an error message from a list of DiagnosticsNodes.

By convention, there should be exactly one ErrorSummary in the list, and it should be the first entry.

Other entries are typically ErrorDescriptions (for material that is always applicable for this error) and ErrorHints (for material that may be sometimes useful, but may not always apply). Other DiagnosticsNode subclasses, such as DiagnosticsStackTrace, may also be used.

When using an ErrorSummary, ErrorDescriptions, and ErrorHints, in debug builds, values interpolated into the message arguments of those classes' constructors are expanded and placed into the DiagnosticsProperty.value property of those objects (which is of type List<Object>). This allows IDEs to examine values interpolated into error messages.

Alternatively, to include a specific Diagnosticable object into the error message and have the object describe itself in detail (see DiagnosticsNode.toStringDeep), consider calling Diagnosticable.toDiagnosticsNode on that object and using that as one of the values passed to this constructor.

In this example, an error is thrown in debug mode if certain conditions are not met. The error message includes a description of an object that implements the Diagnosticable interface, draconis.
void controlDraconis() {
  assert(() {
    if (!draconisAlive || !draconisAmulet) {
      throw FlutterError.fromParts(<DiagnosticsNode>[
        ErrorSummary('Cannot control Draconis in current state.'),
        ErrorDescription('Draconis can only be controlled while alive and while the amulet is wielded.'),
        if (!draconisAlive)
          ErrorHint('Draconis is currently not alive.'),
        if (!draconisAmulet)
          ErrorHint('The Amulet of Draconis is currently not wielded.'),
        draconis.toDiagnosticsNode(name: 'Draconis'),
      ]);
    }
    return true;
  }());
  // ...
}

Implementation

FlutterError.fromParts(this.diagnostics) : assert(diagnostics.isNotEmpty, FlutterError.fromParts(<DiagnosticsNode>[ErrorSummary('Empty FlutterError')])) {
  assert(
    diagnostics.first.level == DiagnosticLevel.summary,
    FlutterError.fromParts(<DiagnosticsNode>[
      ErrorSummary('FlutterError is missing a summary.'),
      ErrorDescription(
        'All FlutterError objects should start with a short (one line) '
        'summary description of the problem that was detected.',
      ),
      DiagnosticsProperty<FlutterError>('Malformed', this, expandableValue: true, showSeparator: false, style: DiagnosticsTreeStyle.whitespace),
      ErrorDescription(
        '\nThis error should still help you solve your problem, '
        'however please also report this malformed error in the '
        'framework by filing a bug on GitHub:\n'
        '  https://github.com/flutter/flutter/issues/new?template=2_bug.md',
      ),
    ]),
  );
  assert(() {
    final Iterable<DiagnosticsNode> summaries = diagnostics.where((DiagnosticsNode node) => node.level == DiagnosticLevel.summary);
    if (summaries.length > 1) {
      final List<DiagnosticsNode> message = <DiagnosticsNode>[
        ErrorSummary('FlutterError contained multiple error summaries.'),
        ErrorDescription(
          'All FlutterError objects should have only a single short '
          '(one line) summary description of the problem that was '
          'detected.',
        ),
        DiagnosticsProperty<FlutterError>('Malformed', this, expandableValue: true, showSeparator: false, style: DiagnosticsTreeStyle.whitespace),
        ErrorDescription('\nThe malformed error has ${summaries.length} summaries.'),
      ];
      int i = 1;
      for (final DiagnosticsNode summary in summaries) {
        message.add(DiagnosticsProperty<DiagnosticsNode>('Summary $i', summary, expandableValue : true));
        i += 1;
      }
      message.add(ErrorDescription(
        '\nThis error should still help you solve your problem, '
        'however please also report this malformed error in the '
        'framework by filing a bug on GitHub:\n'
        '  https://github.com/flutter/flutter/issues/new?template=2_bug.md',
      ));
      throw FlutterError.fromParts(message);
    }
    return true;
  }());
}