I only meant to illustrate the feature, not argue that this specific constructor should use exceptions vs optional return.
Regardless: Why would it be a bad use of exceptions? It reduces the API size and unifies flows, and gives me the option of seeing the specific error. It simply happens to be that in practice I've never needed to know the specific error in this case.
In .NET it’s idiomatic to avoid exceptions for control flow because “it failed to parse” means creating an exception which costs you an allocation and getting the stack trace, among other things.
The allocation is plenty cheap, but creating the stack trace is expensive in pretty much all structured exception systems, and it is noticeable in loops, not necessarily even really tight ones.
So yeah if you’re parsing thousands of url candidates and expect many will not parse, don’t use exceptions to communicate the expected errors. Otherwise don’t worry about it.
Exceptions are nice DX, but theoretically if you were parsing URLs in an inner loop and expecting lots of them to fail it would be very expensive compared to returning a tuple (or Optional, whatever).
If it doesn't return an error code, nor throw an exception, how do you know why it failed? Man, the resistance to exceptions with their human-readable error messages and stack traces and sorely misunderstood on HN. Any time someone says "exception", 50 people show up to point at the boogey man. Why all the fear? I grew up programming in the era of "errno only" (or god forbid: Win32's GetLastError()). It was awful. Exceptions are so much more human-friendly. Most programmers are writing CRUD apps for a business. Exceptions are terrific for this case.
> Man, the resistance to exceptions with their human-readable error messages and stack traces and sorely misunderstood on HN.
You grew up with "errno only", so that's your frame of reference. You've seen exceptions and don't want to go back to errno. Do you "fear" errno? Is errno the "boogey man"?
I've seen monadic error handling and I don't want to go back to exceptions.
There's a range of other options for error handling between a global errno and wrapping every lines in try-catch...
Many languages make it idiomatic for functions to return a value or error (Rust, Go, modern C++) so that you can access a human-friendly error on failure.
Go pretty much uses a global errno, it’s literally analogous, and is a terrible language from an error handling perspective, that failed to learn anything since C.