Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make SelectCatch() from Sprache available in Superpower #87

Open
ewoutkramer opened this issue Mar 27, 2019 · 3 comments
Open

Make SelectCatch() from Sprache available in Superpower #87

ewoutkramer opened this issue Mar 27, 2019 · 3 comments

Comments

@ewoutkramer
Copy link

The Serilog parser has two extension methods SelectCatch(,,string error message) that does a select, but if that select throws, instead results in an error with the given message.

I think these are useful enough to introduce more generally in Superpower.

@ewoutkramer ewoutkramer changed the title Make SelectCatch() from Serilog availabe in Superpower Make SelectCatch() from Serilog available in Superpower Mar 27, 2019
@nblumhardt
Copy link
Member

Great suggestion; I wonder if (since in Superpower we've tried to create more composable building blocks), this could be something like:

p.Catch(e => "some message")

And maybe a generic one that restricts on the Exception type, if we can figure out how to make that sane to call, in the presence of other generic arguments required for parser?

It's also strange that Catch() wouldn't, in some sense, succeed and produce some default value 🤔 ... not sure if there is a better name for it, and/or whether there's some additional/similar parser that could be added for the catch -> default case?

@ewoutkramer
Copy link
Author

p.Catch(e => "some message")

Yes, that would actually be a good way to express it, as that would work in the 'for' part of a LINQ expression too.

I don't know if that's sufficient - since the issue I have is where some of the semantic checks are done in the constructor code of node ypes in my AST. This makes sense in cases where the same check would apply when manually constructing the AST. As these constructors raise exceptions they will be raised in the "select" part of the LINQ query when I construct the AST.

It's also strange that Catch() wouldn't, in some sense, succeed and produce some default value 🤔

You mean that parsing would continue after the catch, a "default" is returned and no message is produced?

marklauter added a commit to marklauter/superpower that referenced this issue Jun 13, 2024
@marklauter
Copy link
Contributor

Something like this?

        /// <summary>
        /// Attempts the parser and invokes the exception handler if the parser throws TException.
        /// </summary>
        /// <typeparam name="TKind">The type of tokens consumed by the parser.</typeparam>
        /// <typeparam name="T">The type of the result.</typeparam>
        /// <typeparam name="TException">The type of exception caught and handled by <see cref="Catch{TKind, T, TException}(TokenListParser{TKind, T}, Func{TException, TokenListParserResult{TKind, T}})"/></typeparam>
        /// <param name="parser">The parser.</param>
        /// <param name="exceptionHandler">A function that handles TException and returns a <see cref="TokenListParserResult{TKind, T}"/>.</param>
        /// <returns>A parser that calls the first parser and handles TException by calling the exception handler.</returns>
        /// <exception cref="ArgumentNullException">Thrown if either the parser or the exceptionHandler is null.</exception>
        public static TokenListParser<TKind, T> Catch<TKind, T, TException>(
            this TokenListParser<TKind, T> parser,
            Func<TException, TokenListParserResult<TKind, T>> exceptionHandler)
            where TException : Exception
        {
            if (parser == null) throw new ArgumentNullException(nameof(parser));
            if (exceptionHandler == null) throw new ArgumentNullException(nameof(exceptionHandler));

            return input =>
            {
                try
                {
                    return parser(input);
                }
                catch (TException ex)
                {
                    return exceptionHandler(ex);
                }
            };
        }

@nblumhardt nblumhardt changed the title Make SelectCatch() from Serilog available in Superpower Make SelectCatch() from Sprache available in Superpower Jun 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants