diff --git a/src/Microsoft.Tye.Core/CoreStrings.resx b/src/Microsoft.Tye.Core/CoreStrings.resx index c1ca0b98..48831107 100644 --- a/src/Microsoft.Tye.Core/CoreStrings.resx +++ b/src/Microsoft.Tye.Core/CoreStrings.resx @@ -169,13 +169,13 @@ Services must have unique names. - Unexpected node type in tye.yaml. Expected "{expected}" but got "{actual}". + Unexpected node type in the tye configuration file. Expected "{expected}" but got "{actual}". - Unexpected key "{key}" in tye.yaml. + Unexpected key "{key}" in the tye configuration file. - Unexpected node type in tye.yaml. Expected one of ({expected}) but got "{actual}". + Unexpected node type in the tye configuration file. Expected one of ({expected}) but got "{actual}". Path "{path}" was not found. diff --git a/src/Microsoft.Tye.Core/Serialization/TyeYamlException.cs b/src/Microsoft.Tye.Core/Serialization/TyeYamlException.cs index e67575be..10610df9 100644 --- a/src/Microsoft.Tye.Core/Serialization/TyeYamlException.cs +++ b/src/Microsoft.Tye.Core/Serialization/TyeYamlException.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.IO; using YamlDotNet.Core; namespace Tye.Serialization @@ -20,7 +21,12 @@ namespace Tye.Serialization } public TyeYamlException(Mark start, string message, Exception? innerException) - : base($"Error parsing tye.yaml: ({start.Line}, {start.Column}): {message}", innerException) + : base($"Error parsing YAML: ({start.Line}, {start.Column}): {message}", innerException) + { + } + + public TyeYamlException(Mark start, string message, Exception? innerException, FileInfo fileInfo) + : base($"Error parsing '{fileInfo.Name}': ({start.Line}, {start.Column}): {message}", innerException) { } diff --git a/src/Microsoft.Tye.Core/Serialization/YamlParser.cs b/src/Microsoft.Tye.Core/Serialization/YamlParser.cs index 259f0512..d507f9f6 100644 --- a/src/Microsoft.Tye.Core/Serialization/YamlParser.cs +++ b/src/Microsoft.Tye.Core/Serialization/YamlParser.cs @@ -42,7 +42,12 @@ namespace Tye.Serialization } catch (YamlException ex) { - throw new TyeYamlException(ex.Start, "Unable to parse tye.yaml. See inner exception.", ex); + if (_fileInfo != null) + { + throw new TyeYamlException(ex.Start, $"Unable to parse '{_fileInfo.Name}'. See inner exception.", ex, _fileInfo); + } + + throw new TyeYamlException(ex.Start, $"Unable to parse YAML. See inner exception.", ex); } var app = new ConfigApplication(); @@ -50,7 +55,7 @@ namespace Tye.Serialization // TODO assuming first document. var document = _yamlStream.Documents[0]; var node = document.RootNode; - ThrowIfNotYamlMapping(node); + ThrowIfNotYamlMapping(node, _fileInfo); app.Source = _fileInfo!; @@ -132,10 +137,15 @@ namespace Tye.Serialization } } - public static void ThrowIfNotYamlMapping(YamlNode node) + public static void ThrowIfNotYamlMapping(YamlNode node, FileInfo? fileInfo = null) { if (node.NodeType != YamlNodeType.Mapping) { + if (fileInfo != null) + { + throw new TyeYamlException(node.Start, + CoreStrings.FormatUnexpectedType(YamlNodeType.Mapping.ToString(), node.NodeType.ToString()), null, fileInfo); + } throw new TyeYamlException(node.Start, CoreStrings.FormatUnexpectedType(YamlNodeType.Mapping.ToString(), node.NodeType.ToString())); } diff --git a/test/UnitTests/TyeDeserializationValidationTests.cs b/test/UnitTests/TyeDeserializationValidationTests.cs index b3ecb2ae..5a19ffa0 100644 --- a/test/UnitTests/TyeDeserializationValidationTests.cs +++ b/test/UnitTests/TyeDeserializationValidationTests.cs @@ -1,4 +1,6 @@ -using Tye; +using System; +using System.IO; +using Tye; using Tye.Serialization; using Xunit; @@ -274,6 +276,24 @@ services: Assert.Contains(errorMessage, exception.Message); } + [Fact] + public void BadYmlFileWithArgs_ThrowsExceptionWithUsefulFilePath() + { + var input = @" +flimflam"; + + using var parser = new YamlParser(input, new FileInfo("foobar.yml")); + try + { + parser.ParseConfigApplication(); + Assert.False(true, "YML parsing exception expected with supplied input"); + } + catch (TyeYamlException e) + { + Assert.StartsWith("Error parsing 'foobar.yml': (2, 1): Unexpected node type in the tye configuration file.", e.Message); + } + } + [Fact] public void DockerFileWithArgs() {