Consider this Swift code snippet that uses explicit error handling. What will be printed when this code runs?
enum FileError: Error { case fileNotFound } func readFile(_ filename: String) throws -> String { if filename == "exists.txt" { return "File content" } else { throw FileError.fileNotFound } } func test() { do { let content = try readFile("missing.txt") print(content) } catch { print("Error caught: \(error)") } } test()
Think about what happens when the file name does not match "exists.txt" and how the error is handled.
The function readFile throws an error if the file name is not "exists.txt". Since "missing.txt" is passed, it throws fileNotFound. The do-catch block catches this error and prints it explicitly.
Why does Swift force programmers to handle errors explicitly using try, catch, or throws?
Think about the benefits of making error handling visible in code.
Swift requires explicit error handling to make it clear where errors can occur and to prevent silent failures or crashes. This helps programmers write safer and more predictable code.
Examine the following Swift code. What error will the compiler report?
func riskyOperation() throws -> Int { return 42 } func test() { let result = riskyOperation() print(result) } test()
Check how functions that throw errors must be called.
The function riskyOperation is marked with throws, so calls to it must use try and handle errors. The code calls it without try, causing a compile-time error.
Given the following Swift code, how many errors will be caught and printed?
enum MyError: Error { case errorOne case errorTwo } func throwError(_ flag: Int) throws { switch flag { case 1: throw MyError.errorOne case 2: throw MyError.errorTwo default: return } } func testErrors() { for i in 0...2 { do { try throwError(i) print("No error for \(i)") } catch { print("Caught error for \(i): \(error)") } } } testErrors()
Count how many times the throwError function throws an error in the loop.
The loop runs for i = 0, 1, 2. For 0, no error is thrown. For 1 and 2, errors are thrown and caught. So 2 errors are caught and printed.
Analyze this Swift code with nested error handling. What will be printed?
enum NetworkError: Error { case disconnected } enum DataError: Error { case corrupted } func fetchData() throws { throw NetworkError.disconnected } func processData() throws { do { try fetchData() } catch NetworkError.disconnected { throw DataError.corrupted } } do { try processData() print("Success") } catch DataError.corrupted { print("Data error caught") } catch { print("Other error caught") }
Follow the error thrown and caught through the nested calls.
fetchData throws NetworkError.disconnected. processData catches that and throws DataError.corrupted. The outer do-catch catches DataError.corrupted and prints "Data error caught".