FlutterError.fromParts constructor Null safety
- 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.
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;
}());
}