Skip to content

Commit fa2dac4

Browse files
committed
fix(parser)!: throw ParsingException for a value that does not convert
A value that does not convert to the property type (for example `Age == "abc"`, `Rating > abc`, or an int overflow) threw FormatException or OverflowException. It now throws ParsingException, with the original exception as the inner exception. BREAKING CHANGE: a bad filter value throws ParsingException, not FormatException or OverflowException. Catch ParsingException or QueryKitException instead. The inner exception keeps the original details.
1 parent 3114c96 commit fa2dac4

5 files changed

Lines changed: 48 additions & 4 deletions

File tree

‎QueryKit.IntegrationTests/Tests/FilterParsingRegressionTests.cs‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ namespace QueryKit.IntegrationTests.Tests;
33
using System.Globalization;
44
using System.Linq.Expressions;
55
using Configuration;
6+
using Exceptions;
67
using FluentAssertions;
78
using Microsoft.EntityFrameworkCore;
89
using Operators;
@@ -324,4 +325,22 @@ public async Task has_returns_matching_rows(string input, string[] expectedTitle
324325
// Assert
325326
recipes.Select(x => x.Title[prefix.Length..]).Should().BeEquivalentTo(expectedTitles);
326327
}
328+
329+
[Theory]
330+
[InlineData("""Age == "abc" """)]
331+
[InlineData("""Age == abc""")]
332+
[InlineData("""Rating > "abc" """)]
333+
[InlineData("""Rating > abc""")]
334+
public async Task invalid_value_throws_parsing_exception(string input)
335+
{
336+
// Arrange
337+
var testingServiceScope = new TestingServiceScope();
338+
339+
// Act
340+
var queryablePeople = testingServiceScope.DbContext().People;
341+
var act = async () => await queryablePeople.ApplyQueryKitFilter(input).ToListAsync();
342+
343+
// Assert
344+
await act.Should().ThrowAsync<ParsingException>();
345+
}
327346
}

‎QueryKit.UnitTests/DotNumberCultureTests.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ public void dot_number_on_an_integer_property_throws_parsing_exception(string cu
3535
[InlineData("de-DE", "Rating ^^ [\"4.0\"]")]
3636
[InlineData("de-DE", "Rating > @4.4")]
3737
[InlineData("de-DE", "HaveMadeItMyself == 4.4")]
38-
public void number_that_v1_14_2_also_converted_throws_format_exception(string cultureName, string input)
38+
public void number_that_v1_14_2_also_converted_throws_parsing_exception(string cultureName, string input)
3939
{
4040
var act = () => WithCulture(cultureName, () => FilterParser.ParseFilter<Recipe>(input));
4141

42-
act.Should().ThrowExactly<FormatException>();
42+
act.Should().ThrowExactly<ParsingException>().WithInnerExceptionExactly<FormatException>();
4343
}
4444

4545
[Fact]

‎QueryKit.UnitTests/FilterParsingRegressionTests.cs‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,23 @@ public void whitespace_around_a_group_gives_the_same_filter(string input, string
342342
result.Should().Equal(expectedResult);
343343
}
344344

345+
[Theory]
346+
[InlineData("""Age == "abc" """)]
347+
[InlineData("""Age == abc""")]
348+
[InlineData("""Rating > "abc" """)]
349+
[InlineData("""Rating > abc""")]
350+
[InlineData("""Age == 99999999999""")]
351+
[InlineData("""Id == "abc" """)]
352+
[InlineData("""SpecificDateTime == "abc" """)]
353+
[InlineData("""Favorite == "abc" """)]
354+
[InlineData("""Age ^^ ["abc"]""")]
355+
public void invalid_value_throws_parsing_exception(string input)
356+
{
357+
var act = () => FilterParser.ParseFilter<TestingPerson>(input);
358+
359+
act.Should().Throw<ParsingException>();
360+
}
361+
345362
private static TResult WithCulture<TResult>(string cultureName, Func<TResult> action)
346363
{
347364
var originalCulture = CultureInfo.CurrentCulture;

‎QueryKit.UnitTests/QueryNameOverUnknownTests.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ public void failure_before_the_query_name_throws_parsing_exception()
4343
}
4444

4545
[Fact]
46-
public void failure_before_the_query_name_throws_its_own_format_exception()
46+
public void failure_before_the_query_name_throws_its_own_parsing_exception()
4747
{
4848
var act = () => FilterParser.ParseFilter<TestingPerson>("""Age > "x" && is adult == true""", Config);
4949

50-
act.Should().ThrowExactly<FormatException>();
50+
act.Should().ThrowExactly<ParsingException>().WithInnerExceptionExactly<FormatException>();
5151
}
5252

5353
[Fact]

‎QueryKit/FilterParser.cs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,14 @@ public static Expression<Func<T, bool>> ParseFilter<T>(string input, IQueryKitCo
6969
{
7070
throw new ParsingException(e);
7171
}
72+
catch (FormatException e)
73+
{
74+
throw new ParsingException(e);
75+
}
76+
catch (OverflowException e)
77+
{
78+
throw new ParsingException(e);
79+
}
7280
finally
7381
{
7482
FilterValue.Parameterize = parameterizeBefore;

0 commit comments

Comments
 (0)