Skip to content

Commit d4fd712

Browse files
authored
Store errors in the asset graph instead of separate files. (#4013)
1 parent effc827 commit d4fd712

File tree

8 files changed

+103
-179
lines changed

8 files changed

+103
-179
lines changed

build_runner_core/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
in the asset graph.
3737
- Track resolver dependencies as library cycle graphs.
3838
- Ignore deprecated analyzer API usages.
39+
- Store errors in the asset graph instead of separate files.
3940

4041
## 8.0.0
4142

build_runner_core/lib/src/asset_graph/graph_loader.dart

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import '../asset_graph/exceptions.dart';
1616
import '../asset_graph/graph.dart';
1717
import '../generate/build_phases.dart';
1818
import '../generate/exceptions.dart';
19-
import '../logging/failure_reporter.dart';
2019
import '../logging/logging.dart';
2120
import '../package_graph/package_graph.dart';
2221
import '../util/constants.dart';
@@ -66,7 +65,6 @@ class AssetGraphLoader {
6665
);
6766
await Future.wait([
6867
writer.deleteDirectory(_generatedOutputDirectoryId),
69-
FailureReporter.cleanErrorCache(),
7068
]);
7169
return null;
7270
}
@@ -111,7 +109,6 @@ class AssetGraphLoader {
111109
writer.delete(assetGraphId),
112110
cachedGraph.deleteOutputs(packageGraph, writer),
113111
writer.deleteDirectory(_generatedOutputDirectoryId),
114-
FailureReporter.cleanErrorCache(),
115112
]);
116113
if (_runningFromSnapshot) {
117114
throw const BuildScriptChangedException();
@@ -126,7 +123,6 @@ class AssetGraphLoader {
126123
writer.delete(assetGraphId),
127124
cachedGraph.deleteOutputs(packageGraph, writer),
128125
writer.deleteDirectory(_generatedOutputDirectoryId),
129-
FailureReporter.cleanErrorCache(),
130126
]);
131127
if (_runningFromSnapshot) {
132128
throw const BuildScriptChangedException();

build_runner_core/lib/src/asset_graph/node.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,8 @@ abstract class GeneratedNodeState
286286
/// [AssetNode.wasOutput].
287287
bool? get result;
288288

289+
BuiltList<String> get errors;
290+
289291
factory GeneratedNodeState(void Function(GeneratedNodeStateBuilder) updates) =
290292
_$GeneratedNodeState;
291293

build_runner_core/lib/src/asset_graph/node.g.dart

Lines changed: 41 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build_runner_core/lib/src/asset_graph/serializers.g.dart

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build_runner_core/lib/src/generate/build.dart

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import '../asset_graph/post_process_build_step_id.dart';
2525
import '../changes/asset_updates.dart';
2626
import '../environment/build_environment.dart';
2727
import '../logging/build_for_input_logger.dart';
28-
import '../logging/failure_reporter.dart';
2928
import '../logging/human_readable_duration.dart';
3029
import '../logging/log_renderer.dart';
3130
import '../logging/logging.dart';
@@ -72,7 +71,6 @@ class Build {
7271
final AssetGraph assetGraph;
7372
final lazyPhases = <String, Future<Iterable<AssetId>>>{};
7473
final lazyGlobs = <AssetId, Future<void>>{};
75-
final failureReporter = FailureReporter();
7674
int actionsCompletedCount = 0;
7775
int actionsStartedCount = 0;
7876
final pendingActions = SplayTreeMap<int, Set<String>>();
@@ -114,6 +112,9 @@ class Build {
114112
/// checked against the digest from the previous build.
115113
final Set<AssetId> changedOutputs = {};
116114

115+
/// Outputs for which errors have been shown.
116+
final Set<AssetId> errorsShownOutputs = {};
117+
117118
/// Whether a graph from [previousLibraryCycleGraphLoader] has any changed
118119
/// transitive source.
119120
final Map<LibraryCycleGraph, bool> changedGraphs = Map.identity();
@@ -170,12 +171,27 @@ class Build {
170171
buildPhases,
171172
);
172173
if (result.status == BuildStatus.success) {
173-
final failures = processedOutputs
174-
.map((id) => assetGraph.get(id)!)
175-
.where((node) => node.type == NodeType.generated)
176-
.where((node) => node.generatedNodeState!.result == false);
174+
final failures = <AssetNode>[];
175+
for (final output in processedOutputs) {
176+
final node = assetGraph.get(output)!;
177+
if (node.type != NodeType.generated) continue;
178+
if (node.generatedNodeState!.result != false) continue;
179+
failures.add(node);
180+
}
177181
if (failures.isNotEmpty) {
178-
await failureReporter.reportErrors(failures);
182+
for (final failure in failures) {
183+
if (errorsShownOutputs.contains(failure.id)) continue;
184+
for (final error in failure.generatedNodeState!.errors) {
185+
final name = _actionLoggerName(
186+
buildPhases.inBuildPhases[failure
187+
.generatedNodeConfiguration!
188+
.phaseNumber],
189+
failure.generatedNodeConfiguration!.primaryInput,
190+
options.packageGraph.root.name,
191+
);
192+
_logger.severe('$name (cached)\n$error');
193+
}
194+
}
179195
result = BuildResult(
180196
BuildStatus.failure,
181197
result.outputs,
@@ -494,7 +510,6 @@ class Build {
494510
}
495511

496512
await _cleanUpStaleOutputs(builderOutputs);
497-
await FailureReporter.clean(phaseNumber, primaryInput);
498513

499514
// Clear input tracking accumulated during `_buildShouldRun`.
500515
readerWriter.inputTracker.clear();
@@ -630,7 +645,6 @@ class Build {
630645
readerWriter.inputTracker.clear();
631646

632647
// Clean out the impacts of the previous run.
633-
await FailureReporter.clean(phaseNumber, input);
634648
final existingOutputs = assetGraph.postProcessBuildStepOutputs(
635649
postProcessBuildStepId,
636650
);
@@ -738,10 +752,10 @@ class Build {
738752
// https://github.com/dart-lang/build/issues/3875.
739753
nodeBuilder.digest = null;
740754
nodeBuilder.generatedNodeState.result = false;
755+
nodeBuilder.generatedNodeState.errors.clear();
741756
});
742757
processedOutputs.add(output);
743758
}
744-
await failureReporter.markSkipped(outputs.map((id) => assetGraph.get(id)!));
745759
}
746760

747761
/// Checks and returns whether any [outputs] need to be updated in
@@ -1191,15 +1205,15 @@ class Build {
11911205
/// - Setting `digest` based on what was written.
11921206
/// - Setting `result` based on action success.
11931207
/// - Setting `inputs` based on `inputTracker` and `unusedAssets`.
1194-
/// - Storing the error message with the [failureReporter].
1208+
/// - Setting `errors`.
11951209
/// - Updating `newPrimaryInputs` and `changedOutputs` as needed.
11961210
Future<void> _setOutputsState(
11971211
AssetId input,
11981212
Iterable<AssetId> outputs,
11991213
SingleStepReaderWriter readerWriter,
12001214
InputTracker inputTracker,
12011215
String actionDescription,
1202-
Iterable<ErrorReport> errors, {
1216+
Iterable<String> errors, {
12031217
Set<AssetId>? unusedAssets,
12041218
}) async {
12051219
if (outputs.isEmpty) return;
@@ -1232,22 +1246,15 @@ class Build {
12321246
nodeBuilder.generatedNodeState
12331247
..inputs.replace(usedInputs)
12341248
..resolverEntrypoints.replace(inputTracker.resolverEntrypoints)
1235-
..result = result;
1249+
..result = result
1250+
..errors.replace(errors);
12361251
nodeBuilder.digest = digest;
12371252
});
12381253

1239-
if (!result) {
1240-
// Mark this output as failed. Transitive outputs will be marked as
1241-
// failed when they are processed and notice their primary inputs
1242-
// have failed.
1243-
await failureReporter.markReported(
1244-
actionDescription,
1245-
outputNode,
1246-
errors,
1247-
);
1248-
}
1249-
12501254
processedOutputs.add(output);
1255+
if (result == false) {
1256+
errorsShownOutputs.add(output);
1257+
}
12511258
}
12521259
}
12531260

build_runner_core/lib/src/logging/build_for_input_logger.dart

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,15 @@
44

55
import 'dart:async';
66

7+
import 'package:build/build.dart';
78
import 'package:logging/logging.dart';
89

9-
import 'failure_reporter.dart';
10-
1110
/// A delegating [Logger] that records if any logs of level >= [Level.SEVERE]
1211
/// were seen.
1312
class BuildForInputLogger implements Logger {
1413
final Logger _delegate;
1514

16-
final errorsSeen = <ErrorReport>[];
15+
final errorsSeen = <String>[];
1716

1817
BuildForInputLogger(this._delegate);
1918

@@ -64,7 +63,7 @@ class BuildForInputLogger implements Logger {
6463
Zone? zone,
6564
]) {
6665
if (logLevel >= Level.SEVERE) {
67-
errorsSeen.add(ErrorReport('$message', '${error ?? ''}', stackTrace));
66+
errorsSeen.add(_renderError(message, error, stackTrace));
6867
}
6968
_delegate.log(logLevel, message, error, stackTrace, zone);
7069
}
@@ -80,13 +79,13 @@ class BuildForInputLogger implements Logger {
8079

8180
@override
8281
void severe(Object? message, [Object? error, StackTrace? stackTrace]) {
83-
errorsSeen.add(ErrorReport('$message', '${error ?? ''}', stackTrace));
82+
errorsSeen.add(_renderError(message, error, stackTrace));
8483
_delegate.severe(message, error, stackTrace);
8584
}
8685

8786
@override
8887
void shout(Object? message, [Object? error, StackTrace? stackTrace]) {
89-
errorsSeen.add(ErrorReport('$message', '${error ?? ''}', stackTrace));
88+
errorsSeen.add(_renderError(message, error, stackTrace));
9089
_delegate.shout(message, error, stackTrace);
9190
}
9291

@@ -96,4 +95,23 @@ class BuildForInputLogger implements Logger {
9695

9796
@override
9897
Stream<Level?> get onLevelChanged => _delegate.onLevelChanged;
98+
99+
String _renderError(
100+
Object? message, [
101+
Object? error,
102+
StackTrace? stackTrace,
103+
]) {
104+
var result = message?.toString() ?? '';
105+
if (error != null) result += '\n$error';
106+
107+
// Drop stack traces for exception types that can be caused by normal
108+
// user input; render stack traces for everything else as they can point to
109+
// bugs in generators or in build_runner.
110+
if (stackTrace != null &&
111+
error is! SyntaxErrorInAssetException &&
112+
error is! UnresolvableAssetException) {
113+
result += '\n$stackTrace';
114+
}
115+
return result;
116+
}
99117
}

0 commit comments

Comments
 (0)