diff --git a/src/LEGO.AsyncAPI.Readers/AsyncApiReaderSettings.cs b/src/LEGO.AsyncAPI.Readers/AsyncApiReaderSettings.cs
index c9534d20..f949164d 100644
--- a/src/LEGO.AsyncAPI.Readers/AsyncApiReaderSettings.cs
+++ b/src/LEGO.AsyncAPI.Readers/AsyncApiReaderSettings.cs
@@ -39,6 +39,12 @@ public class AsyncApiReaderSettings : AsyncApiSettings
public ReferenceResolutionSetting ReferenceResolution { get; set; } =
ReferenceResolutionSetting.ResolveInternalReferences;
+ ///
+ /// Indicates what should happen when unmapped members are encountered during deserialization.
+ /// Error and Warning will add an error or warning to the diagnostics object.
+ ///
+ public UnmappedMemberHandling UnmappedMemberHandling { get; set; } = UnmappedMemberHandling.Error;
+
///
/// Dictionary of parsers for converting extensions into strongly typed classes.
///
diff --git a/src/LEGO.AsyncAPI.Readers/ParseNodes/PropertyNode.cs b/src/LEGO.AsyncAPI.Readers/ParseNodes/PropertyNode.cs
index 11120606..2313f30d 100644
--- a/src/LEGO.AsyncAPI.Readers/ParseNodes/PropertyNode.cs
+++ b/src/LEGO.AsyncAPI.Readers/ParseNodes/PropertyNode.cs
@@ -29,8 +29,7 @@ public void ParseField(
IDictionary> fixedFields,
IDictionary, Action> patternFields)
{
- var found = fixedFields.TryGetValue(this.Name, out var fixedFieldMap);
-
+ var _ = fixedFields.TryGetValue(this.Name, out var fixedFieldMap);
if (fixedFieldMap != null)
{
try
@@ -78,8 +77,12 @@ public void ParseField(
}
else
{
- this.Context.Diagnostic.Errors.Add(
- new AsyncApiError(string.Empty, $"{this.Name} is not a valid property at {this.Context.GetLocation()}"));
+ switch (this.Context.Settings.UnmappedMemberHandling)
+ {
+ case UnmappedMemberHandling.Error:
+ this.Context.Diagnostic.Errors.Add(new AsyncApiError(string.Empty, $"{this.Name} is not a valid property at {this.Context.GetLocation()}"));
+ break;
+ }
}
}
}
diff --git a/src/LEGO.AsyncAPI.Readers/UnmappedMemberHandling.cs b/src/LEGO.AsyncAPI.Readers/UnmappedMemberHandling.cs
new file mode 100644
index 00000000..b58c34c4
--- /dev/null
+++ b/src/LEGO.AsyncAPI.Readers/UnmappedMemberHandling.cs
@@ -0,0 +1,20 @@
+// Copyright (c) The LEGO Group. All rights reserved.
+
+namespace LEGO.AsyncAPI.Readers
+{
+ ///
+ /// Unmapped member handling.
+ ///
+ public enum UnmappedMemberHandling
+ {
+ ///
+ /// Add error to diagnostics for unmapped members.
+ ///
+ Error,
+
+ ///
+ /// Ignore unmapped members.
+ ///
+ Ignore,
+ }
+}
diff --git a/src/LEGO.AsyncAPI.Readers/V2/AsyncApiAvroSchemaDeserializer.cs b/src/LEGO.AsyncAPI.Readers/V2/AsyncApiAvroSchemaDeserializer.cs
index 013ec856..5015cef2 100644
--- a/src/LEGO.AsyncAPI.Readers/V2/AsyncApiAvroSchemaDeserializer.cs
+++ b/src/LEGO.AsyncAPI.Readers/V2/AsyncApiAvroSchemaDeserializer.cs
@@ -3,6 +3,7 @@
namespace LEGO.AsyncAPI.Readers
{
using System;
+ using LEGO.AsyncAPI.Exceptions;
using LEGO.AsyncAPI.Models;
using LEGO.AsyncAPI.Readers.Exceptions;
using LEGO.AsyncAPI.Readers.ParseNodes;
@@ -169,7 +170,7 @@ public static AvroSchema LoadSchema(ParseNode node)
mapNode.ParseFields(ref union, UnionFixedFields, UnionMetadataPatternFields);
return union;
default:
- throw new InvalidOperationException($"Unsupported type: {type}");
+ throw new AsyncApiException($"Unsupported type: {type}");
}
}
diff --git a/test/LEGO.AsyncAPI.Tests/AsyncApiReaderTests.cs b/test/LEGO.AsyncAPI.Tests/AsyncApiReaderTests.cs
index 0a4cd5e7..20716506 100644
--- a/test/LEGO.AsyncAPI.Tests/AsyncApiReaderTests.cs
+++ b/test/LEGO.AsyncAPI.Tests/AsyncApiReaderTests.cs
@@ -5,6 +5,7 @@ namespace LEGO.AsyncAPI.Tests
using System;
using System.Collections.Generic;
using System.Linq;
+ using FluentAssertions;
using LEGO.AsyncAPI.Exceptions;
using LEGO.AsyncAPI.Models;
using LEGO.AsyncAPI.Models.Interfaces;
@@ -30,6 +31,7 @@ public void Read_WithExtensionParser_Parses()
info:
title: test
version: 1.0.0
+ test: 1234
contact:
name: API Support
url: https://www.example.com/support
@@ -57,6 +59,7 @@ public void Read_WithExtensionParser_Parses()
{
{ extensionName, valueExtensionParser },
},
+ UnmappedMemberHandling = UnmappedMemberHandling.Ignore,
};
var reader = new AsyncApiStringReader(settings);
@@ -64,6 +67,96 @@ public void Read_WithExtensionParser_Parses()
Assert.AreEqual((doc.Channels["workspace"].Extensions[extensionName] as AsyncApiAny).GetValue(), 1234);
}
+ [Test]
+ public void Read_WithUnmappedMemberHandlingError_AddsError()
+ {
+ var extensionName = "x-someValue";
+ var yaml = $"""
+ asyncapi: 2.3.0
+ info:
+ title: test
+ version: 1.0.0
+ test: 1234
+ contact:
+ name: API Support
+ url: https://www.example.com/support
+ email: support@example.com
+ channels:
+ workspace:
+ {extensionName}: onetwothreefour
+ """;
+ Func valueExtensionParser = (any) =>
+ {
+ if (any.TryGetValue(out var value))
+ {
+ if (value == "onetwothreefour")
+ {
+ return new AsyncApiAny(1234);
+ }
+ }
+
+ return new AsyncApiAny("No value provided");
+ };
+
+ var settings = new AsyncApiReaderSettings
+ {
+ ExtensionParsers = new Dictionary>
+ {
+ { extensionName, valueExtensionParser },
+ },
+ UnmappedMemberHandling = UnmappedMemberHandling.Error,
+ };
+
+ var reader = new AsyncApiStringReader(settings);
+ var doc = reader.Read(yaml, out var diagnostic);
+ diagnostic.Errors.Should().HaveCount(1);
+ }
+
+ [Test]
+ public void Read_WithUnmappedMemberHandlingIgnore_NoErrors()
+ {
+ var extensionName = "x-someValue";
+ var yaml = $"""
+ asyncapi: 2.3.0
+ info:
+ title: test
+ version: 1.0.0
+ test: 1234
+ contact:
+ name: API Support
+ url: https://www.example.com/support
+ email: support@example.com
+ channels:
+ workspace:
+ {extensionName}: onetwothreefour
+ """;
+ Func valueExtensionParser = (any) =>
+ {
+ if (any.TryGetValue(out var value))
+ {
+ if (value == "onetwothreefour")
+ {
+ return new AsyncApiAny(1234);
+ }
+ }
+
+ return new AsyncApiAny("No value provided");
+ };
+
+ var settings = new AsyncApiReaderSettings
+ {
+ ExtensionParsers = new Dictionary>
+ {
+ { extensionName, valueExtensionParser },
+ },
+ UnmappedMemberHandling = UnmappedMemberHandling.Ignore,
+ };
+
+ var reader = new AsyncApiStringReader(settings);
+ var doc = reader.Read(yaml, out var diagnostic);
+ diagnostic.Errors.Should().HaveCount(0);
+ }
+
[Test]
public void Read_WithThrowingExtensionParser_AddsToDiagnostics()
{