Handle version not parsing gracefully (#3929)
diff --git a/lib/src/lock_file.dart b/lib/src/lock_file.dart
index f725260..48de2fd 100644
--- a/lib/src/lock_file.dart
+++ b/lib/src/lock_file.dart
@@ -168,8 +168,9 @@
packageEntries,
(name, spec) {
// Parse the version.
- final versionEntry = _getStringEntry(spec, 'version');
- final version = Version.parse(versionEntry);
+ final versionEntry =
+ _getEntry<YamlScalar>(spec, 'version', 'version string');
+ final version = _parseVersion(versionEntry);
// Parse the source.
final sourceName = _getStringEntry(spec, 'source');
@@ -243,7 +244,7 @@
return fn();
} on FormatException catch (e) {
throw SourceSpanFormatException(
- 'Invalid $description: ${e.message}',
+ '$description: ${e.message}',
span,
);
}
@@ -257,6 +258,14 @@
);
}
+ static Version _parseVersion(YamlNode node) {
+ return _parseNode(
+ node,
+ 'version',
+ parse: Version.parse,
+ );
+ }
+
static String _getStringEntry(YamlMap map, String key) {
return _parseNode<String>(
_getEntry<YamlScalar>(map, key, 'string'),
@@ -275,19 +284,19 @@
final value = node.value;
if (parse != null) {
if (value is! String) {
- _failAt('Expected a $typeDescription.', node);
+ _failAt('Expected a $typeDescription', node);
}
return _wrapFormatException(
- 'Expected a $typeDescription.',
+ 'Expected a $typeDescription',
node.span,
() => parse(node.value),
);
} else if (value is T) {
return value;
}
- _failAt('Expected a $typeDescription.', node);
+ _failAt('Expected a $typeDescription', node);
}
- _failAt('Expected a $typeDescription.', node);
+ _failAt('Expected a $typeDescription', node);
}
static void _parseEachEntry<K, V>(
diff --git a/test/lock_file_test.dart b/test/lock_file_test.dart
index 3dbcf92..9fa7081 100644
--- a/test/lock_file_test.dart
+++ b/test/lock_file_test.dart
@@ -7,6 +7,7 @@
import 'package:pub/src/source/hosted.dart';
import 'package:pub/src/system_cache.dart';
import 'package:pub_semver/pub_semver.dart';
+import 'package:source_span/source_span.dart';
import 'package:test/test.dart' hide Description;
import 'package:yaml/yaml.dart';
@@ -135,7 +136,7 @@
sources,
);
},
- throwsFormatException,
+ throwsSourceSpanException,
);
});
@@ -149,7 +150,7 @@
sources,
);
},
- throwsFormatException,
+ throwsSourceSpanException,
);
});
@@ -166,7 +167,7 @@
sources,
);
},
- throwsFormatException,
+ throwsSourceSpanException,
);
});
@@ -184,7 +185,7 @@
sources,
);
},
- throwsFormatException,
+ throwsSourceSpanException,
);
});
@@ -201,7 +202,7 @@
sources,
);
},
- throwsFormatException,
+ throwsSourceSpanException,
);
});
@@ -218,7 +219,7 @@
sources,
);
},
- throwsFormatException,
+ throwsSourceSpanException,
);
});
@@ -236,54 +237,54 @@
sources,
);
},
- throwsFormatException,
+ throwsSourceSpanException,
);
});
test("throws if the old-style SDK constraint isn't a string", () {
expect(
() => LockFile.parse('sdk: 1.0', sources),
- throwsFormatException,
+ throwsSourceSpanException,
);
});
test('throws if the old-style SDK constraint is invalid', () {
expect(
() => LockFile.parse('sdk: oops', sources),
- throwsFormatException,
+ throwsSourceSpanException,
);
});
test("throws if the sdks field isn't a map", () {
expect(
() => LockFile.parse('sdks: oops', sources),
- throwsFormatException,
+ throwsSourceSpanException,
);
});
test("throws if an sdk constraint isn't a string", () {
expect(
() => LockFile.parse('sdks: {dart: 1.0}', sources),
- throwsFormatException,
+ throwsSourceSpanException,
);
expect(
() {
LockFile.parse('sdks: {dart: 1.0.0, flutter: 1.0}', sources);
},
- throwsFormatException,
+ throwsSourceSpanException,
);
});
test('throws if an sdk constraint is invalid', () {
expect(
() => LockFile.parse('sdks: {dart: oops}', sources),
- throwsFormatException,
+ throwsSourceSpanException,
);
expect(
() {
LockFile.parse('sdks: {dart: 1.0.0, flutter: oops}', sources);
},
- throwsFormatException,
+ throwsSourceSpanException,
);
});
@@ -411,3 +412,5 @@
});
});
}
+
+final throwsSourceSpanException = throwsA(isA<SourceSpanException>());