I define all custom Errors using enum
(s), like:
public enum MyErrorEnum: String, LocalizedError {
case FileNotFound = "Failed to find file."
public var errorDescription: String? { rawValue }
}
But some errors require additional context
, like adding file-path to the message.
Unfortunately, because Swift enums don't support instance variables, I tried workarounds, like:
private var KEY_CONTEXT: UInt8 = 0;
public enum MyErrorEnum: String, LocalizedError {
case FileNotFound = "Failed to find file."
public var errorDescription: String? { rawValue }
public var context: String {
return objc_getAssociatedObject(self as NSObject, &KEY_CONTEXT)
as? String ?? "";
}
@discardableResult
public mutating func withContext(_ value: String) -> Self {
objc_setAssociatedObject(
self as NSObject, &KEY_CONTEXT, value as NSString,
.OBJC_ASSOCIATION_RETAIN_NONATOMIC);
return self;
}
}
Note that above does not raise any compile and/or runtime error in Xcode 12, but just did not work.
And later, I was notified that Xcode 13 raises compile error below: "
Cannot convert value of type 'MyErrorEnum' to type 'NSObject' in coercion
"
I also already tried simply changing String
to a custom StringWithContext
class which implements ExpressibleByStringLiteral
, but NOT even that did work (probably because enum's rawValue
is somehow change protected).