This worked for me:

enum NetworkException: ErrorType {
    case NoInternetError, SecurityError
}

enum ParseException: ErrorType {
    case FailedResponse(statusCode: Int)
    case EmptyResponse
    case MissingField(fieldName: String)
}

enum ChangePictureError: ErrorType {
    case Network(NetworkException)
    case Parse(ParseException)
}

func thing() throws {
    throw ChangePictureError.Parse(.FailedResponse(statusCode: 401))
}

func thing2() {
    do {
        try thing()
    } catch ChangePictureError.Parse(.FailedResponse(statusCode: 401)) {
        print("401")
    } catch {
        print("some other error")
    }
}

I must admit that I’ve generally avoided exceptions (aka using Java) throughout 
my entire programming career thus far and so don’t have extensive experience 
with this sort of situation. :)

l8r
Sean


> On Dec 18, 2015, at 1:03 PM, Dennis Lysenko <[email protected]> 
> wrote:
> 
> 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

Reply via email to