2016-01-19 21 views
9

使用Swift現在一些函數被標記爲throws,這迫使開發者調用do - try catch塊內的函數。 但開發人員如何知道該函數引發的不同異常列表?如何獲取函數拋出的錯誤列表?

作爲參考,在這裏是Java代碼行:

static void employeeAge(int age) throws MyExceptionA,MyExceptionB 

這裏是明確指出,例外是2 MyExceptionAMyExceptionB和開發人員可以決定採取不同的行動取決於錯誤的。

我們可以在Swift上實現嗎?

+0

Unfortanely,你必須檢查dokumentation(API)。要小心,沒有異常拋出,但拋出錯誤。如果您正在尋找如何組織代碼流的方法,請改用適當的檢查。捕捉拋出錯誤是您最後一次從中恢復的機會,您無法從異常中恢復。 – user3441734

+0

[另請參閱此相關問題和接受的答案。](http://stackoverflow.com/questions/31977738/how-to-find-the-kind-of-errors-a-method-may-throw-and-趕上他們在迅速) – Suragch

回答

4

執行 - 抓住當斯威夫特文檔說,一個功能throws,他們的意思是它拋出一個ErrorType(在通常的NSError可可的API),也不例外。

考慮爲NSFileManagercreateDirectoryAtPath以下do-try-catch流量:

let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] 

do { 
    try NSFileManager.defaultManager().createDirectoryAtPath(documentsPath, withIntermediateDirectories: false, attributes: nil) 
} catch { 
    // 'error' variable automatically populated 
    print(error) 
    print(error.dynamicType) 
} 

createDirectoryAtPath將失敗,因爲文件的目錄已經存在。記錄的errordynamicType表明,它實際上是一個NSError對象:

Error Domain=NSCocoaErrorDomain Code=516 "The file 「Documents」 couldn’t be saved in the folder 「35B0B3BF-D502-4BA0-A991-D07568AB87C6」 because a file with the same name already exists." UserInfo={NSFilePath=/Users/jal/Library/Developer/CoreSimulator/Devices/E8A35774-C9B7-42F0-93F1-8103FBBC7118/data/Containers/Data/Application/35B0B3BF-D502-4BA0-A991-D07568AB87C6/Documents, NSUnderlyingError=0x7fa88bd14410 {Error Domain=NSPOSIXErrorDomain Code=17 "File exists"}} 

NSError 

爲了看不同類型的錯誤的功能,可以throw,你就必須檢查error信息確定拋出錯誤的類型,以及如何處理每個錯誤。在NSError的情況下,這將是其域,代碼和描述。

在這種特殊情況下,該路徑中已存在一個目錄,因此文件管理器無法創建新目錄。如果文件管理器沒有寫訪問權限,則此操作可能失敗的另一個原因的示例是。這將是錯誤代碼256.

+1

除了純粹的swift錯誤...唯一的要求是拋出錯誤符合ErrorType protokol。這並不意味着它是一個NSError對象。 – user3441734

+0

@ user3441734我在Cocoa Touch API或文檔中看不到任何「純」錯誤,這只是一個使用Apple提供的方法的例子。你能否給我一個「純粹」Swift錯誤的Docs例子?此外,['ErrorType'被'NSError'採用。](https://developer.apple.com/library/ios/documentation/Swift/Reference/Swift_ErrorType_Protocol/index.html) – JAL

+0

無論哪種方式,都沒有不同拋出的錯誤類型。所有的錯誤都是'NSError'類型或符合'ErrorType'協議。您必須查看錯誤的具體描述或錯誤代碼才能找出問題所在。 – JAL

-1

您在catch之後編寫一個模式以指示該子句可以處理的錯誤。

do { 
    try expression 
    statements 
} catch pattern 1 { 
    statements 
} catch pattern 2 where condition { 
    statements 
} 

見段處理錯誤使用Swift Programming Language

+4

問題是我如何得到一個函數拋出的所有可能的錯誤列表。如果我不知道這個列表,我不能指定哪些是我知道如何處理的。 – IgnazioC

0

我有與OP完全相同的問題。由於沒有人真正回答這個問題(和我一樣),這裏是我的貢獻。

在Swift 3和Xcode 8.3.3中,您可以按如下方式處理個別異常。下面我會給你一個FileManager的例子。

首先,您將只有一個catch塊來捕捉方法拋出的錯誤。然後你將把這個錯誤當作NSError。與Swift中的錯誤協議相反,NSError是一個REAL錯誤類。然後,您可以在switch語句中提取該錯誤的代碼。您將必須知道該方法從哪個域引發錯誤,然後在適當的頭文件中找到錯誤代碼。

在我下面的例子中,文件相關的錯誤在NSCocoaErrorDomain中拋出,這些錯誤代碼在Foundation/FoundationErrors.h中定義/列出。在我的電腦,它們分別位於

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Versions/C/Headers/FoundationErrors.h 

適用於MacOS應用程序,並在

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/Foundation.framework/Headers/ 

的iPhone應用程序。

所以這裏有一個例子:

let home = FileManager.default.homeDirectoryForCurrentUser 
let file = home.appendingPathComponent("file") 
do { 
    let loadedString = try String(contentsOf: file) 
} 
catch { 
    let realError = error as NSError // As weird as it looks, Xcode actually wants this forced conversion 
    print(realError.localizedDescription) 
    switch realError.code { 
    case 257: // No permission 
     handleNoPermission() 
    case 260: // File not found 
     handleFileNotFound() 
    default: 
     handleUndefinedError() 
    } 
} 

.localizedDescription包含用戶的有關錯誤語言的用戶友好的消息。如果上面沒有找到文件,則打印:The file 「file」 couldn’t be opened because there is no such file.英文。它意味着直接用在您向用戶展示的錯誤對話框中。

你也可能會發現什麼錯誤是由這裏的每個域拋出的更多信息:https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ErrorHandlingCocoa/ErrorObjectsDomains/ErrorObjectsDomains.html