refactor(dart/transform): Show friendly messages for transform failures

Previously, the error messages coming out of the Dart transformer were
opaque when those errors came from the analyzer (for example, analyzer
parse errors). Log more useful errors when they are caught by the
transform code.
This commit is contained in:
Tim Blasi 2015-08-05 17:39:37 -07:00
parent 07b9be798c
commit 3db0ae1dac
2 changed files with 46 additions and 5 deletions

View File

@ -1,6 +1,8 @@
library angular2.transform.common.logging;
import 'dart:async';
import 'package:analyzer/analyzer.dart';
import 'package:barback/barback.dart';
import 'package:code_transformers/messages/build_logger.dart';
import 'package:source_span/source_span.dart';
@ -11,11 +13,36 @@ typedef _SimpleCallback();
final _key = #loggingZonedLoggerKey;
/// Executes {@link fn} inside a new {@link Zone} with its own logger.
dynamic initZoned(Transform t, _SimpleCallback fn) =>
Future<dynamic> initZoned(Transform t, _SimpleCallback fn) =>
setZoned(new BuildLogger(t), fn);
dynamic setZoned(BuildLogger logger, _SimpleCallback fn) {
return runZoned(fn, zoneValues: {_key: logger});
Future<dynamic> setZoned(BuildLogger logger, _SimpleCallback fn) async {
return runZoned(() async {
try {
await fn();
} on AnalyzerError catch (e) {
// Do not worry about printing the stack trace, barback will handle that
// on its own when it catches the rethrown exception.
logger
.error(' Failed with ${e.runtimeType}\n${_friendlyError(e.error)}');
rethrow;
} on AnalyzerErrorGroup catch (eGroup) {
// See above re: stack trace.
var numErrors = eGroup.errors.length;
if (numErrors == 1) {
logger.error(_friendlyError(eGroup.errors[0].error));
} else {
var buf = new StringBuffer();
buf.writeln(' Failed with ${numErrors} errors');
for (var i = 0; i < numErrors; ++i) {
buf.writeln(
'Error ${i + 1}: ${_friendlyError(eGroup.errors[i].error)}');
}
logger.error('$buf');
}
rethrow;
}
}, zoneValues: {_key: logger});
}
/// The logger for the current {@link Zone}.
@ -59,3 +86,17 @@ class PrintLoggerError extends Error {
'Span: ${Error.safeToString(span)}.';
}
}
/// Generate a human-readable error message from `error`.
String _friendlyError(AnalysisError error) {
if (error.source != null) {
var file =
new SourceFile(error.source.contents.data, url: error.source.fullName);
return file
.span(error.offset, error.offset + error.length)
.message(error.message, color: false);
} else {
return '<unknown location>: ${error.message}';
}
}

View File

@ -25,7 +25,7 @@ void allTests() {
inputPath = 'directive_linker/simple_files/$inputPath';
var actual = formatter
.format(await linkNgDeps(reader, new AssetId('a', inputPath)));
expect(actual).toEqual(expected);
expect(actual).toEqual(formatter.format(expected));
}
});
@ -41,7 +41,7 @@ void allTests() {
inputPath = 'directive_linker/simple_export_files/$inputPath';
var actual = formatter
.format(await linkNgDeps(reader, new AssetId('a', inputPath)));
expect(actual).toEqual(expected);
expect(actual).toEqual(formatter.format(expected));
}
});
}