> On Feb 20, 2017, at 1:15 PM, Joe Groff via swift-evolution > <[email protected]> wrote: > > >> On Feb 20, 2017, at 9:57 AM, John McCall via swift-evolution >> <[email protected] <mailto:[email protected]>> wrote: >> >>> On Feb 19, 2017, at 3:04 PM, Anton Zhilin via swift-evolution >>> <[email protected] <mailto:[email protected]>> wrote: >>> It’s expected that if you need resilience, then you will throw an “open” >>> enum. Essentially, we pass resilience of typed throws on to those who will >>> hopefully establish resilience of enums. >>> >>> If you prefer separate error types, then declare a base protocol for all >>> your error types and throw a protocol existential. You won’t even need >>> default case in switches, if closed protocols make it into the language. >>> >>> I don’t like any solution that is based on comments. I think that compiler >>> should always ignore comments. >>> >> I agree. And in general, this sort of thing is exactly my core concern >> about adding typed throws to the language: I am completely certain that many >> programmers will add typed throws annotations because they're programmers >> and thus, well, probably a little obsessive/compulsive, and they're trying >> to precisely document the behavior of their function without necessarily >> thinking about the usefulness of that information for their clients and (if >> they're writing a library; and really you should almost always be writing >> code as if you're writing a library) whether they're actually willing to >> commit to that behavior in their interface. For those programmers, typed >> throws is just going to box them in and force them into anti-patterns in the >> long run. >> >> In the vast majority of use-cases, clients are not going to exhaustively >> handle all errors — they will always have some generic fall-back. That is >> not pessimism, it's actually the natural result of the complicated world we >> live in, where code can fail for a huge host of reasons and most callers >> won't have meaningful special-case behavior for all of them. (On most >> operating systems, opening a file or a network connection can fail because >> you ran out of file descriptors. You're seriously telling me that you're >> going to add a special case to your error logic for that?) Go look at the >> actual error types that people use in most typed-throws situations and try >> to tell me I'm wrong — they probably have like twenty alternatives, and >> solidly a quarter or more of them will just be embedding some other >> arbitrarily-complex or stringly-typed error value. > > I agree that overly specific API specs are a concern. There's still some > documentational benefit to a typed error enum, even if it ultimately ends up > containing a catch-all case, since it gives you the ability to also enumerate > some number of discrete, realistically handleable cases. Sure, your network > request running in an XPC service has infinitely many failure cases due to > resource constraints or IPC failure or network chaos, but there's usually > some number of domain-specific error cases too. And if we compare the > proposed "you get to specify one error enum type" model to, say, Java or > C++98's "you get to specify any number of error classes" model, I think that > helps steer people away from the most grievous API mistakes in Java land, > since instead of listing a closed set of concrete error classes directly in > your API signature, you'll list those error cases in your enum definition, > and in a resilient world, the enum will be "open" by default to external > users, preventing it from being a permanent liability unless the user > explicitly opted into closedness.
Realistically there are only rarely actionable error cases and usually only one or two; everything else just bubbles up to the top of the current operation where you retry or report a permanent failure. If the enum is open then you need a default catch-all error handling case anyway, so what benefit is there to typed throws that you don’t get with documentation comments? I’m positive John is right about what will happen in practice. > > In the discussions around Rust's error handling conventions, they recognized > this pattern of APIs either raising some number of layer-appropriate errors > or carrying forward the failure modes of the layers below them, and they > developed a convention for errors wrapping other errors. It would be > reasonable to say we should do the same thing as part of the typed errors > design. If we were to generalize enum subtyping beyond Optional, that might > be one way to go about it, letting an enum wrap its underlying layers' > failure cases as subtypes. > > -Joe Yeah but Rust has a macro system so error-chain makes re-wrapping trivial. A simple `chain_err(|| “my new error message”)` is enough to define and “throw” a new error that wraps the underlying error. Russ
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
