Unobvious behavior

If you try to create NSError with it's inherited initializer from NSObject (aka NSError()), you will get an invalid object. More details:
Documentation says you cannot initialize NSError with null domain parameter. But using of inherited initializer simply does it:

Screenshot 2020-05-27 at 22.26.40

Looks like this is unobvious behavior/bug, because each invocation of NSError() will produce invalid object. We need to provide some default value for domain (empty string, i.e., but not null)

This is a common issue with types inherited from Obj-C / Foundation, as there are often unsupported initializers that you can still call. I think this is a limitation of Obj-C or the Swift overlay but I'm not sure.

In general you shouldn't need to use NSError from Swift, unless you're bridging to Obj-C in a way that requires some specific NSError feature that can't come from native Swift errors.

Sounds like Apple should have marked it with NS_UNAVAILABLE (as in this StackOverflow answer, which I believe is from @hamishknight).

It’s worth filing an Apple bug report about it. If it had that attribute, Swift‘s importer would respect it and you wouldn’t be able to call the plain init.

3 Likes

Thanks to all, I've reported this bug to the Apple. Also, I noted that call of NSError() will print such message in debug:
-[NSError init] called; this results in an invalid NSError instance. It will raise an exception in a future release. Please call errorWithDomain:code:userInfo: or initWithDomain:code:userInfo:. This message shown only once.
Answers from StackOverflow tell us that this behavior was in 2015, so possibly it's time to fix this (throw an exception right in init, or using NS_UNAVAILABLE, which for me is better)

1 Like