diff --git a/CHANGELOG.md b/CHANGELOG.md
index 27e580f..f6b7c9c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 4.11.0 (2020-10-09)
+**Summary* - Allow handling unrecognized rows when using schema selectors.
+
+Previously, if a record was encountered that could be handled by any of the configured schemas, the selector would throw a generic `FlatFilesException`. Now, a `RecordProcessingException`is thrown instead, which can be ignored causing the record to be skipped.
+
## 4.10.0 (2020-10-06)
**Summary** - Add the ability to explicitly write the schema using typed writers.
diff --git a/FlatFiles.Test/FixedLengthMultipleSchemaTester.cs b/FlatFiles.Test/FixedLengthMultipleSchemaTester.cs
index 5882532..37d86fe 100644
--- a/FlatFiles.Test/FixedLengthMultipleSchemaTester.cs
+++ b/FlatFiles.Test/FixedLengthMultipleSchemaTester.cs
@@ -155,6 +155,27 @@ 46.9 23.45 True
Assert.IsFalse(reader.Read());
}
+ [TestMethod]
+ [ExpectedException(typeof(RecordProcessingException))]
+ public void TestReader_UnknownType()
+ {
+ var stringReader = new StringReader("What's this weird thing?");
+ var selector = getSchemaSelector();
+ var reader = new FixedLengthReader(stringReader, selector);
+
+ reader.Read();
+ }
+
+ [TestMethod]
+ public void TestReader_UnknownType_IgnoreUnknown_SkipsRecord()
+ {
+ var stringReader = new StringReader("What's this weird thing?");
+ var selector = getSchemaSelector();
+ var reader = new FixedLengthReader(stringReader, selector);
+ reader.RecordError += (o, e) => e.IsHandled = true;
+ Assert.IsFalse(reader.Read());
+ }
+
private FixedLengthTypeMapperSelector getTypeMapperSelector()
{
var selector = new FixedLengthTypeMapperSelector();
diff --git a/FlatFiles.Test/SeparatedValueMultipleSchemaTester.cs b/FlatFiles.Test/SeparatedValueMultipleSchemaTester.cs
index 3a4a95b..fd5bbdf 100644
--- a/FlatFiles.Test/SeparatedValueMultipleSchemaTester.cs
+++ b/FlatFiles.Test/SeparatedValueMultipleSchemaTester.cs
@@ -201,6 +201,27 @@ public void TestTypeMapper_ReadThreeTypes_WithMetadataRecord()
Assert.IsFalse(reader.Read());
}
+ [TestMethod]
+ [ExpectedException(typeof(RecordProcessingException))]
+ public void TestReader_UnknownType()
+ {
+ var stringReader = new StringReader("What's this weird thing?");
+ var selector = getSchemaSelector();
+ var reader = new SeparatedValueReader(stringReader, selector);
+
+ reader.Read();
+ }
+
+ [TestMethod]
+ public void TestReader_UnknownType_IgnoreUnknown_SkipsRecord()
+ {
+ var stringReader = new StringReader("What's this weird thing?");
+ var selector = getSchemaSelector();
+ var reader = new SeparatedValueReader(stringReader, selector);
+ reader.RecordError += (o, e) => e.IsHandled = true;
+ Assert.IsFalse(reader.Read());
+ }
+
private SeparatedValueTypeMapperSelector getTypeMapperSelector(bool hasMetadata = false)
{
var selector = new SeparatedValueTypeMapperSelector();
diff --git a/FlatFiles/FixedLengthReader.cs b/FlatFiles/FixedLengthReader.cs
index 727b6e5..ce7e2fb 100644
--- a/FlatFiles/FixedLengthReader.cs
+++ b/FlatFiles/FixedLengthReader.cs
@@ -413,7 +413,13 @@ private FixedLengthSchema GetSchema(string record)
{
return metadata.ExecutionContext.Schema;
}
- return schemaSelector.GetSchema(record);
+ FixedLengthSchema schema = schemaSelector.GetSchema(record);
+ if (schema != null)
+ {
+ return schema;
+ }
+ ProcessError(new RecordProcessingException(metadata, Resources.MissingMatcher));
+ return null;
}
private string ReadNextRecord()
diff --git a/FlatFiles/FixedLengthSchemaSelector.cs b/FlatFiles/FixedLengthSchemaSelector.cs
index dddb0cb..11b1a8f 100644
--- a/FlatFiles/FixedLengthSchemaSelector.cs
+++ b/FlatFiles/FixedLengthSchemaSelector.cs
@@ -92,7 +92,7 @@ internal FixedLengthSchema GetSchema(string record)
defaultMatcher.Action?.Invoke();
return defaultMatcher.Schema;
}
- throw new FlatFileException(Resources.MissingMatcher);
+ return null;
}
private class SchemaMatcher
diff --git a/FlatFiles/FlatFiles.csproj b/FlatFiles/FlatFiles.csproj
index d888413..8c5af23 100644
--- a/FlatFiles/FlatFiles.csproj
+++ b/FlatFiles/FlatFiles.csproj
@@ -10,17 +10,17 @@
https://github.com/jehugaleahsa/FlatFiles.git
git
csv;comma;tab;separated;value;delimited;flat;file;fixed;width;fixed-width;length;fixed-length;parser;parsing;parse
- Allow explicitly writing the schema using typed mappers.
+ Allow handling unrecognized rows when using schema selectors.
true
FlatFiles.snk
- 4.10.0
+ 4.11.0
8.0
- 4.10.0.0
- 4.10.0.0
+ 4.11.0.0
+ 4.11.0.0
UNLICENSE.txt
icon.png
diff --git a/FlatFiles/SeparatedValueReader.cs b/FlatFiles/SeparatedValueReader.cs
index 54c3c81..3c728af 100644
--- a/FlatFiles/SeparatedValueReader.cs
+++ b/FlatFiles/SeparatedValueReader.cs
@@ -360,11 +360,24 @@ private SeparatedValueSchema GetSchema(string[] rawValues)
{
return metadata.ExecutionContext.Schema;
}
- return schemaSelector.GetSchema(rawValues);
+ SeparatedValueSchema schema = schemaSelector.GetSchema(rawValues);
+ if (schema != null)
+ {
+ return schema;
+ }
+ ProcessError(new RecordProcessingException(metadata, Resources.MissingMatcher));
+ return null;
}
private bool IsSkipped(string[] values)
{
+ if (metadata.ExecutionContext.Schema == null && schemaSelector != null)
+ {
+ // A schema was not found by the selector for the given record.
+ // If we got here then we know the raised exception was handled and suppressed.
+ // Therefore we skip the record and go on to the next one.
+ return true;
+ }
if (RecordRead == null)
{
return false;
diff --git a/FlatFiles/SeparatedValueSchemaSelector.cs b/FlatFiles/SeparatedValueSchemaSelector.cs
index f9179c1..b3a9726 100644
--- a/FlatFiles/SeparatedValueSchemaSelector.cs
+++ b/FlatFiles/SeparatedValueSchemaSelector.cs
@@ -99,7 +99,7 @@ internal SeparatedValueSchema GetSchema(string[] values)
defaultMatcher.Action?.Invoke();
return defaultMatcher.Schema;
}
- throw new FlatFileException(Resources.MissingMatcher);
+ return null;
}
private class SchemaMatcher