swiftnserror

How do you create an NSError object with underlying errors?


For unit testing purposes, I need to be able to create an NSError object with the underlyingErrors property set to a certain error.


Solution

  • You should always favor using the declared vars like NSPOSIXErrorDomain or NSCocoaErrorDomain instead of string literals. Note that there are already declared CocoaError and POSIXError structs that you can use to generate those errors:

    func createFilesystemError() -> NSError {
        NSError(
            domain: CocoaError.errorDomain,
            code: CocoaError.fileNoSuchFile.rawValue,
            userInfo: [
                NSUnderlyingErrorKey: NSError(
                    domain: POSIXError.errorDomain,
                    code: Int(POSIXError.ENOENT.rawValue)
                )
            ]
        )
    }
    

    But the correct way to create these erros is to initialize and cast them to NSError if needed:

    extension CocoaError {
        static let fileNotFound: CocoaError = .init(
            .fileNoSuchFile,
            userInfo: [
                NSUnderlyingErrorKey: POSIXError(.ENOENT)
            ]
        )
    }
    

    extension NSError {
        static let fileNotFound = CocoaError.fileNotFound as NSError
    }
    

    createFilesystemError() == .fileNotFound   // true