hexdreamer
(Kenny Leung)
1
Hi All.
I'd like to log to the console every time an error is used. I thought it would be easy to just create an initializer on an enum and do a print inside there, like so:
public enum MyErrors : Error {
case invalidArgument(String) // message
init() {
print("Error!")
}
}
However, when I try to compile this, I get the error:
'self.init' isn't called on all paths before returning from initializer
I clearly don't understand enums. How can I call self.init from init?
Any help is greatly appreciated.
michelf
(Michel Fortin)
2
Using one of the cases to initialize an enum isn't going to call the initializer. The initializer must be called directly, like so:
let e = MyErrors()
However, for this to work the initializer needs to choose one of the cases itself. Something like that:
init() {
self = .invalidArgument("hello")
}
This will quiet the error you see, although I know this is not really what you want. There's unfortunately no way to call code when you're using one of the cases to initialize the enum.
You can actually simulate this if you really need to:
public enum MyErrors : Error {
case _invalidArgument(String) // message
static func invalidArgument(_ s: String) -> MyErrors {
print("Error!")
return _invalidArgument(String)
}
}
The syntax from the caller side will be exactly the same.
lukasa
(Cory Benfield)
4
This is a really key limitation. Users will always be able to use .invalidArgument to create an error of this type.
If you want to do this, you'll likely be better served by making your error a struct, instead of an enum.
hexdreamer
(Kenny Leung)
5
Thanks for your answers. Since I generally thing it's a bad thing to go against the grain of the tool, it's probably a better idea to create a custom throwing function to put everything in.