Skip to content

Commit ab20e22

Browse files
authored
Extend ParseException with InnerException and StackTrace (#717)
* Extend ParseException with InnerException and StackTrace. * x
1 parent 586ba45 commit ab20e22

File tree

3 files changed

+33
-18
lines changed

3 files changed

+33
-18
lines changed

src/System.Linq.Dynamic.Core/Exceptions/ParseException.cs

+22-11
Original file line numberDiff line numberDiff line change
@@ -9,39 +9,50 @@ namespace System.Linq.Dynamic.Core.Exceptions
99
/// <summary>
1010
/// Represents errors that occur while parsing dynamic linq string expressions.
1111
/// </summary>
12-
#if !(SILVERLIGHT || WINDOWS_APP || UAP10_0 || NETSTANDARD || PORTABLE || WPSL || NETSTANDARD2_0)
12+
#if !(SILVERLIGHT || WINDOWS_APP || UAP10_0 || NETSTANDARD || PORTABLE || WPSL || NETSTANDARD2_0)
1313
[Serializable]
1414
#endif
1515
public sealed class ParseException : Exception
1616
{
17+
/// <summary>
18+
/// The location in the parsed string that produced the <see cref="ParseException"/>.
19+
/// </summary>
20+
public int Position { get; }
21+
1722
/// <summary>
1823
/// Initializes a new instance of the <see cref="ParseException"/> class with a specified error message and position.
1924
/// </summary>
2025
/// <param name="message">The message that describes the error.</param>
2126
/// <param name="position">The location in the parsed string that produced the <see cref="ParseException"/></param>
22-
public ParseException(string message, int position)
23-
: base(message)
27+
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference if no inner exception is specified.</param>
28+
public ParseException(string message, int position, Exception? innerException = null) : base(message, innerException)
2429
{
2530
Position = position;
2631
}
2732

28-
/// <summary>
29-
/// The location in the parsed string that produced the <see cref="ParseException"/>.
30-
/// </summary>
31-
public int Position { get; }
32-
3333
/// <summary>
3434
/// Creates and returns a string representation of the current exception.
3535
/// </summary>
3636
/// <returns>A string representation of the current exception.</returns>
3737
public override string ToString()
3838
{
39-
return string.Format(CultureInfo.CurrentCulture, Res.ParseExceptionFormat, Message, Position);
39+
var text = string.Format(CultureInfo.CurrentCulture, Res.ParseExceptionFormat, Message, Position);
40+
41+
if (InnerException != null)
42+
{
43+
text = $"{text} ---> {InnerException}{Environment.NewLine} --- End of inner exception stack trace ---";
44+
}
45+
46+
if (StackTrace != null)
47+
{
48+
text = $"{text}{Environment.NewLine}{StackTrace}";
49+
}
50+
51+
return text;
4052
}
4153

4254
#if !(SILVERLIGHT || WINDOWS_APP || UAP10_0 || NETSTANDARD || PORTABLE || WPSL || NETSTANDARD2_0)
43-
ParseException(SerializationInfo info, StreamingContext context)
44-
: base(info, context)
55+
private ParseException(SerializationInfo info, StreamingContext context) : base(info, context)
4556
{
4657
Position = (int)info.GetValue("position", typeof(int));
4758
}

src/System.Linq.Dynamic.Core/Parser/StringParser.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ public static string ParseString(string s)
3434
}
3535
catch (Exception ex)
3636
{
37-
throw new ParseException(ex.Message, 0);
37+
throw new ParseException(ex.Message, 0, ex);
3838
}
3939
}
4040
}
41-
}
41+
}

test/System.Linq.Dynamic.Core.Tests/Parser/StringParserTests.cs

+9-5
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,17 @@ public void StringParser_With_InvalidStringQuoteCharacter_ThrowsException(string
4848
public void StringParser_With_UnexpectedUnrecognizedEscapeSequence_ThrowsException()
4949
{
5050
// Arrange
51-
string input = new string(new[] { '"', '\\', 'u', '?', '"' });
51+
var input = new string(new[] { '"', '\\', 'u', '?', '"' });
5252

5353
// Act
5454
Action action = () => StringParser.ParseString(input);
5555

5656
// Assert
57-
action.Should().Throw<ParseException>();
57+
var parseException = action.Should().Throw<ParseException>();
58+
59+
parseException.Which.InnerException!.Message.Should().Contain("Insufficient hexadecimal digits");
60+
61+
parseException.Which.StackTrace.Should().Contain("at System.Linq.Dynamic.Core.Parser.StringParser.ParseString(String s) in ").And.Contain("System.Linq.Dynamic.Core\\Parser\\StringParser.cs:line ");
5862
}
5963

6064
[Theory]
@@ -65,7 +69,7 @@ public void StringParser_With_UnexpectedUnrecognizedEscapeSequence_ThrowsExcepti
6569
public void StringParser_Parse_SingleQuotedString(string input, string expectedResult)
6670
{
6771
// Act
68-
string result = StringParser.ParseString(input);
72+
var result = StringParser.ParseString(input);
6973

7074
// Assert
7175
result.Should().Be(expectedResult);
@@ -92,10 +96,10 @@ public void StringParser_Parse_SingleQuotedString(string input, string expectedR
9296
public void StringParser_Parse_DoubleQuotedString(string input, string expectedResult)
9397
{
9498
// Act
95-
string result = StringParser.ParseString(input);
99+
var result = StringParser.ParseString(input);
96100

97101
// Assert
98102
result.Should().Be(expectedResult);
99103
}
100104
}
101-
}
105+
}

0 commit comments

Comments
 (0)