0

I'm migrating some code originally written in Swift2 to Swift4. I've completed the Swift3 intermediate upgrade and am hitting some errors in Xcode9 regarding some user defined enum uses outside their source file.

Consider the following partial project structure...

Project
  --EnumDefs
  ----ExceptionTypes.swift
  --UI
  ----UseExceptions.swift

ExceptionTypes.swift

enum MyError : Error {
    case err1
    case err2
}
...

UseExceptions.swift

...
    do {
        ...
    }  catch MyError.err1(let e) {
        print("\(e)")
    }  catch let e {
        print("\(e)")
    } 

...

I've also tried the variant syntax I've seen online of

catch let e as MyError.err1 {

still no luck, I'm seeing the compiler error:

Enum element 'err1' is not a member type of 'MyError'

I'm tried making the MyError scope to be defined public which didn't work. I get a sense that I may be missing an import or something. I'm not sure if it matters but Autocomplete in Xcode from the UseExceptions.swift file does recognize when I begin typing MyError.

Is there anything special to using definitions between swift files across a sibling directory like shown above? Or is there something else wrong here with the way Swift 4 deals with exception handling?

Tal Zion
  • 6,308
  • 3
  • 50
  • 73
jxramos
  • 7,356
  • 6
  • 57
  • 105
  • This is not how you use errors read about it here https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html – zombie Mar 13 '18 at 19:41
  • Could be a breakage in the substantive use of `e` where the source is trying to print it out, conceivably with a fancy formatting of the call stack or something along those lines. I did see the documentation maybe I missed something but I didn't see an example of how to catch one of the derived Error types and still use the thrown Error in the body of the catch. – jxramos Mar 13 '18 at 19:48
  • This part of the documentation is curious regarding my mention of the call stack.... `Unlike exception handling in many languages—including Objective-C—error handling in Swift does not involve unwinding the call stack, a process that can be computationally expensive.` Was such a design always in Swift or did it change in later releases? – jxramos Mar 13 '18 at 19:54

2 Answers2

1

You are missing an associatedValue, case err1(String)

func test() throws {
    throw MyError.err1("error")
}

enum MyError : Error {
    case err1(String)
    case err2
}

do {
    try test()
} catch MyError.err1(let e) {
    print(e)
}
Tal Zion
  • 6,308
  • 3
  • 50
  • 73
  • That's interesting, I'd have to define a message in the throw MyError.err1 which otherwise yields `Thrown expression type '(String) -> MyError' does not conform to 'Error'` – jxramos Mar 13 '18 at 20:36
-1

Looks like @zombie was right, it was a matter of old style Exception handling. I removed the substantive use of the print("\(e)") from the err1 handler and the compiler error went away.

I'm curious what the exception handling capabilities were like in Swift 2 that allowed the earlier syntax and exception object usage.

jxramos
  • 7,356
  • 6
  • 57
  • 105