C# – How to design a TryParse method which provides detailed information in case of a parsing error

api-designcnet

When parsing user input, it is generally recommended to not to throw and catch exceptions but rather to use validation methods. In the .NET BCL, this would be the difference between, for example, int.Parse (throws an exception on invalid data) and int.TryParse (returns false on invalid data).

I am designing my own

Foo.TryParse(string s, out Foo result)

method and I'm unsure about the return value. I could use bool like .NET's own TryParse method, but that would give no indication about the type of error, about the exact reason why s could not be parsed into a Foo. (For example, s could have unmatched parenthesis, or the wrong number of characters, or a Bar without a corresponding Baz, etc.)

As a user of APIs, I strongly dislike methods which just return a success/failure Boolean without telling me why the operation failed. This makes debugging a guessing game, and I don't want to impose that on my library's clients either.

I can think of a lot of workarounds to this issue (return status codes, return an error string, add an error string as an out parameter), but they all have their respective downsides, and I also want to stay consistent with the conventions of the .NET Framework.

Thus, my question is as follows:

Are there methods in the .NET Framework which (a) parse input without throwing exceptions and (b) still return more detailed error information than a simple true/false Boolean?

Best Answer

I would recommend using the monad pattern for your return type.

ParseResult<Foo> foo = FooParser.Parse("input");

Note also, it should not be Foo's responsibility to figure out how it should be parsed from user input as this directly binds your domain layer to your UI layer, and also violates the single responsibility principal.

You can also make a parse result class specific to Foo instead of using generics, depending on your use case.

A foo specific parse result class might look something like this:

class FooParseResult
{
     Foo Value { get; set; }
     bool PassedRequirement1 { get; set; }
     bool PassedRequirement2 { get; set; }
}

Here is the Monad version:

class ParseResult<T>
{
     T Value { get; set; }
     string ParseErrorMessage { get; set; }
     bool WasSuccessful { get; set; }
}

I am not aware of any methods in the .net framework that return detailed parse error information.