I am working on a piece of code that is going to fetch an array of NSManagedObject
s from CoreData. When using a do catch statement in my code it doesn't seem right to do it this way, but it is the simplest way I can write this line of code.
In any other scenario when you use the return
statement you are jumping out of the current function you are in. And you can be assured that no other code in your function will execute past the return
statement. I am wondering if the same applies to Swift's do catch
paradigm.
class func getAll() -> [MMNotification] {
let context = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<MMNotification>(entityName: "MMNotification")
do {
return try context.fetch(fetchRequest)
}
catch {
// Will this 'catch' if the try fails,
// even if we said we are 'return'ing right before the 'try'?
return []
}
}
Here I am fetching a list of notifications stored in CoreData. In the do
block you can see the line of code in question.
QUESTION
Will the catch
block execute if the try
fails after already stating that the function should return
?
What you have should work as expected. Basically what happens is if a throw occurs at any time within a do, the catch is called and any code after the throw will not be executed.
Yes, the catch
block will execute if the try
in return try
fails. The return will not happen.
Here's a little code to prove it to yourself. Paste it into a new playground to try it out.
import UIKit
let shouldFail = true
enum DemoError:Error {
case shouldFail
}
func failableGetter() throws -> String {
if shouldFail { throw DemoError.shouldFail }
return "Succeeded"
}
func fetchInfo() -> String {
do {
return try failableGetter()
} catch {
return "Failed"
}
}
print(fetchInfo()) // "Failed" or "Succeeded" depending on shouldFail
When shouldFail
is true
, the failableGetter()
throws an error and the do-catch
in fetchInfo()
skips to the catch section before returning.
When shouldFail
is false
, the failableGetter()
doesn't fail and fetchInfo()
returns the result.
Adding to this answer. Scope matters a bit here. Code inside the do
block code after a throw will NOT be executed. However, code further down outside of the scope of the do
block will be executed. I made a simple playground you can run to see for yourself.
import Foundation
let error = NSError(domain: "", code: 123, userInfo: [NSLocalizedDescriptionKey: "My error"])
func functionThatAlwaysThrows() throws {
throw(error)
}
func myFunction() {
do {
try functionThatAlwaysThrows()
// This will never print
print("Continuing after throw inside do scope")
} catch let err {
print("Caught Error: \(err.localizedDescription)")
}
// This will always print
print("Continuing after throw outside do scope")
}
Output:
Caught Error: My error
Continuing after throw outside do scope
If you want more information on Error handling you can take a look at the docs
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With