Как найти ошибки, которые метод может бросить и поймать в Swift

Я использую NSFileManager.contentsOfDirectoryAtPath, чтобы получить массив имен файлов в каталоге. Я хочу использовать новый синтаксис do-try-catch для обработки ошибок:

do {

    let docsArray = try fileManager.contentsOfDirectoryAtPath(docsPath)

} catch {

    // handle errors
    print(error) // this is the best I can currently do

}

Я могу представить, что ошибка может заключаться в том, что docsPath не существует, но я не знаю, как поймать эту ошибку. И я не знаю, какие могут быть другие возможные ошибки.

Пример документации

Документация по обработке ошибок имеет пример, подобный этому

enum VendingMachineError: ErrorType {
    case InvalidSelection
    case InsufficientFunds(centsNeeded: Int)
    case OutOfStock
}

и

do {
    try vend(itemNamed: "Candy Bar")
    // Enjoy delicious snack
} catch VendingMachineError.InvalidSelection {
    print("Invalid Selection.")
} catch VendingMachineError.OutOfStock {
    print("Out of Stock.")
} catch VendingMachineError.InsufficientFunds(let amountNeeded) {
    print("Insufficient funds. Please insert an additional \(amountNeeded) cents.")
}

но я не знаю, как сделать что-то подобное, чтобы поймать ошибки стандартных типов Swift, которые имеют методы с использованием ключевого слова throws.

Ссылка NSFileManager для contentsOfDirectoryAtPath не говорит о том, какие ошибки могут быть возвращены. Поэтому я не знаю, какие ошибки поймать или как их обработать, если я их получу.

Update

Я хотел бы сделать что-то вроде этого:

do {
    let docsArray = try fileManager.contentsOfDirectoryAtPath(docsPath)
} catch FileManagerError.PathNotFound {
    print("The path you selected does not exist.")
} catch FileManagerError.PermissionDenied {
    print("You do not have permission to access this directory.")
} catch ErrorType {
    print("An error occured.")
}

Ответ 1

NSError автоматически соединяется с ErrorType, где домен становится типом (например, NSCocoaErrorDomain становится NSCocoaError), а код ошибки становится значением (NSFileReadNoSuchFileError становится .FileReadNoSuchFileError)

import Foundation

let docsPath = "/file/not/found"
let fileManager = NSFileManager()

do {
    let docsArray = try fileManager.contentsOfDirectoryAtPath(docsPath)
} catch NSCocoaError.FileReadNoSuchFileError {
    print("No such file")
} catch {
    // other errors
    print(error)
}

Как узнать, какая ошибка может быть возвращена конкретным вызовом, может помочь только документация. Почти все ошибки Foundation являются частью домена NSCocoaError и могут быть найдены в FoundationErrors.h (хотя есть некоторые редкие ошибки, когда Foundation также может иногда возвращать ошибки POSIX в NSPOSIXErrorDomain), но эти, возможно, не были полностью перекрыты, поэтому вам придется отказаться от управления ими на уровне NSError.

Более подробную информацию можно найти в "Использование Swift с Cocoa и Objective-C (Swift 2.2)"

Ответ 2

Он вернет NSError:

let fileManager = NSFileManager()

do {

    let docsArray = try fileManager.contentsOfDirectoryAtPath("/")

} catch let error as NSError {

    // handle errors
    print(error.localizedDescription)

    // The file "Macintosh HD" couldn’t be opened because you don’t have permission to view it.
}

Ответ 3

То, что вы спрашиваете в части "обновления", невозможно. Это решение функции бросания, чтобы вы знали, что он может бросить или не показывать, а затем вам нужно обработать общую ошибку.

Многие функции раскрывают информацию о заброшенных ошибках - например:

func startVPNTunnel() throws
Description 
Start the process of connecting the VPN
true if the process of connecting the VPN started successfully, false if an error occurred.
Parameters  
error   
A pointer to a pointer to an NSError object. If specified and the VPN connection process cannot be started due to an error, this parameter will be set to point to an NSError object containing details about the error. See NEVPNManager Class Reference for a list of possible errors.

Изменить: возможная причина для этого - в этом случае функция throwing может изменить ошибки, которые она вызывает, и весь код, который поймает эту ошибку, будет по-прежнему действителен.