Sean, it would, but then we get into the whole "Well, this throws ChangePictureError, which could be a NetworkException, or a ParseException" thing...sound at all familiar? "Well, this throws IOException, which could be FileNotFoundException, MalformedURLException, ProtocolException, ObjectStreamException, UnsupportedEncodingException, SSLException...". I guess I am just saying there is still some work to be done with regards to wrapping and rethrowing exceptions.
How would you catch a Parse with statusCode==401 in a catch statement? On Fri, Dec 18, 2015 at 1:49 PM Sean Heber <[email protected]> wrote: > I may just not be understanding what this is trying to solve, but the > following would work too, wouldn’t it? > > enum NetworkException { > case NoInternetError, SecurityError > } > > enum ParseException { > case FailedResponse(statusCode: Int) > case EmptyResponse > case MissingField(fieldName: String) > } > > enum ChangePictureError { > case Network(NetworkException) > case Parse(ParseException) > etc.. > } > > l8r > Sean > > > > On Dec 18, 2015, at 12:42 PM, T.J. Usiyan via swift-evolution < > [email protected]> wrote: > > > > I think that you can accomplish this right now if you make your backing > enum literal convertible. String literal would have been the better choice > in the example below but I was feeling lazy. > > > > public enum MyLibError: ErrorType, IntegerLiteralConvertible { > > case FileNotFound > > case UnexpectedEOF > > case PermissionDenied > > // ... 300 cases later > > case FluxCapacitorFailure > > case SplineReticulationError > > case UnknownError > > > > public init(integerLiteral value: Int) { > > switch value { > > case 0: > > self = .FileNotFound > > case 1: > > self = .UnexpectedEOF > > case 2: > > self = .PermissionDenied > > case 3: > > self = .FluxCapacitorFailure > > case 4: > > self = .SplineReticulationError > > default: > > self = .UnknownError > > } > > } > > } > > > > enum FileSystemError: MyLibError { > > case FileNotFound = 0 > > case UnexpectedEOF = 1 > > case PermissionDenied = 2 > > } > > > > On Fri, Dec 18, 2015 at 12:34 PM, Dennis Lysenko via swift-evolution < > [email protected]> wrote: > > Sorry, I got a bit too excited and skimmed over the most important part > of the idea. So this is a special type of enum declaration in which you > cannot declare any new enum members. I personally have not seen a use for > this in my code but I would love to hear others' response to it. It is a > very interesting idea though. > > > > I'm going to go out on a limb with an idea that is in the same vein as > this one: What if we favored composition over inheritance here, and made it > so that you could transparently refer to members of other enums *without* > having another enum as a backing type? > > > > e.g., you have: > > enum NetworkException { > > case NoInternetError, SecurityError > > } > > > > enum ParseException { > > case FailedResponse(statusCode: Int) > > case EmptyResponse > > case MissingField(fieldName: String) > > } > > > > As two general classes of errors. But for a full API call wrapper, you > might want an error class that composes the two, so that when calling the > API call from your UI code, you can display a "please check your > connection" message for NoInternetError, a "Please log in" error for > FailedResponse with statusCode=401, or a "server error" message for any of > the rest. > > > > I wonder how do you and others feel about that use-case? I have > certainly seen it come up a lot in real-world projects that require > resilient UI interactions with nontrivial networking operations. > > > > Here are some quick code samples off the top of my head for how we might > go about this (let's say the API operation is "change profile picture": > > > > enum ChangePictureError { > > include NetworkException > > include ParseException > > case PictureTooLarge > > } > > > > or > > > > enum ChangePictureError { > > compose NetworkException.NoInternetError > > compose ParseException.EmptyResponse > > compose ParseException.FailedResponse(statusCode: Int) > > case PictureTooLarge > > } > > > > Not a proposal by any stretch of the imagination, just a potential > direction inspired by your idea, Felix. > > > > > > On Fri, Dec 18, 2015 at 12:21 PM Dennis Lysenko < > [email protected]> wrote: > > Felix, > > > > This seems to be very interestingly tied into your comments about > polymorphism in 'throws' type annotations. Would you not feel that allowing > enums to be built on top of other enums would promote the kind of egregious > proliferation of exception polymorphism that discourages so many from > following Java's checked exception model? > > > > On Fri, Dec 18, 2015 at 11:29 AM Félix Cloutier < > [email protected]> wrote: > > Hi all, > > > > Swift currently has more or less three conceptual types of enums: > discriminated unions, lists of unique tokens, and lists of value of a raw > type. > > > > > // Discriminated unions > > > enum Foo { > > > case Bar(Int) > > > case Baz(String) > > > } > > > > > > // Lists of unique tokens (mixable with discriminated unions) > > > enum Foo { > > > case Frob > > > case Nicate > > > } > > > > > > // Lists of raw values > > > enum Foo: String { > > > case Bar = "Bar" > > > case Baz = "Baz" > > > } > > > > I think that the last case could be made more interesting if you could > use more types as underlying types. For instance, it could probably be > extended to support another enum as the backing type. One possible use case > would be to have a big fat enum for all the possible errors that your > program/library can throw, but refine that list into a shorter enum for > functions that don't need it all. > > > > > enum MyLibError: ErrorType { > > > case FileNotFound > > > case UnexpectedEOF > > > case PermissionDenied > > > // ... 300 cases later > > > case FluxCapacitorFailure > > > case SplineReticulationError > > > } > > > > > > enum FileSystemError: MyLibError { > > > case FileNotFound = .FileNotFound > > > case UnexpectedEOF = .UnexpectedEOF > > > case PermissionDenied = .PermissionDenied > > > } > > > > This example could be made simpler if the `= .Foo` part was inferred > from the name, but you get the idea. > > > > In this case, it would be helpful (but not required) that > FileSystemError was convertible into a MyLibError, so that it could be > transparently rethrown in a function that uses the larger enum. I > personally don't see why enums with a specified underlying type can't be > implicitly converted to it, but this is not currently the case and it > probably deserves some discussion as well. > > > > Is there any interest in that? > > > > Félix > > > > _______________________________________________ > > swift-evolution mailing list > > [email protected] > > https://lists.swift.org/mailman/listinfo/swift-evolution > > > > > > _______________________________________________ > > swift-evolution mailing list > > [email protected] > > https://lists.swift.org/mailman/listinfo/swift-evolution > > > > > > _______________________________________________ > > swift-evolution mailing list > > [email protected] > > https://lists.swift.org/mailman/listinfo/swift-evolution > >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
