Your "attempt" function addresses this  issue if someone only wants to print 
the error:

guard let x = attempt({ try throwingFunction(y) }) else {
         return
}
// prints "Error \(trimmedFileName):\(lineNumber) \(error)"

In contrast to

guard let x = try? throwingFunction(y) catch {
        // you have to make your own print
        return
}

---------------------

However if you want to handle the error before you exit the scope it is quite 
inconvenient:

guard let x = attempt({ _, _, error in /* handle error */ }, { try 
throwingFunction(y) } ) else {
        return
}

In contrast to:

guard let x = try? throwingFunction(y) catch {
        // handle error
        return
}

- Maximilian

> Am 14.03.2016 um 18:00 schrieb Erica Sadun <[email protected]>:
> 
>> On Mar 14, 2016, at 10:20 AM, Maximilian Hünenberger via swift-evolution 
>> <[email protected]> wrote:
>> 
>> How about only allowing "guard try? catch":
>> 
>>     guard let x = try? foo() catch { ... }
>> 
>> This would address both concerns of Chris:
>> 
>> • "This is inconsistent with what we currently have, because “if let” and 
>> “guard let” match against an optional and succeed iff the optional is 
>> present."
>> 
>> • "This shouldn’t be tied to the presence of try, because it already means 
>> something (that the enclosed expression can throw).  This:
>>         guard let x = try foo() …
>> Already means “call foo, if it throws, propagate the error.  If not, test 
>> the returned optional”."
>> 
>> 
>> With "try?" it is clear that "foo()" doesn't throw an error in the guard 
>> expression and guard matches against an optional. This makes it unambiguous 
>> to "guard try else" which throws in this case.
>> 
>> Kind regards
>> - Maximilian
> 
> 
> 
> I'm not a fan of the notion of guard/catch. However, it occurs to me that my 
> "attempt" code may address this issue.
> I've recently updated it to take an arbitrary error handler, which if 
> omitted, simply prints the error. Otherwise it acts like try?
> or if you set crashOnError, like try!. It works with guard.
> 
> -- E
> 
> github: 
> https://github.com/erica/SwiftUtility/blob/master/Sources/CoreError.swift
> 
> public typealias CommonErrorHandlerType = (String, Int, ErrorType) -> Void
> 
> /// Replacement for `try?` that introduces an error handler
> /// The default handler prints an error before returning nil
> ///
> /// - Parameter file: source file, derived from `__FILE__` context literal
> /// - Parameter line: source line, derived from `__LINE__` context literal
> /// - Parameter crashOnError: defaults to false. When set to true
> ///   will raise a fatal error, emulating try! instead of try?
> /// - Parameter errorHandler: processes the error, returns nil
> ///
> /// ```swift
> /// attempt {
> ///   let mgr = NSFileManager.defaultManager()
> ///   try mgr.createDirectoryAtPath(
> ///     "/Users/notarealuser",
> ///     withIntermediateDirectories: true,
> ///     attributes: nil)
> /// }
> /// ```
> ///
> public func attempt<T>(
>     file fileName: String = __FILE__,
>     line lineNumber: Int = __LINE__,
>     crashOnError: Bool = false,
>     errorHandler: CommonErrorHandlerType = {
>         // Default handler prints context:error and returns nil
>         fileName, lineNumber, error in
>         
>         /// Retrieve last path component because #fileName is
>         /// not yet a thing in Swift
>         let trimmedFileName: String = (fileName as NSString).lastPathComponent
>         
>         /// Force print and return nil like try?
>         print("Error \(trimmedFileName):\(lineNumber) \(error)")
>     },
>     closure: () throws -> T) -> T? {
>         
>         do {
>             // Return executes only if closure succeeds, returning T
>             return try closure()
>             
>         } catch {
>             // Emulate try! by crashing
>             if crashOnError {
>                 print("Fatal error \(fileName):\(lineNumber): \(error)")
>                 fatalError()
>             }
>             
>             // Execute error handler and return nil
>             errorHandler(fileName, lineNumber, error)
>             return nil
>         }
> }
> 
> 
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution
  • Re: [swift-evolution] Idea: Ex... Maximilian Hünenberger via swift-evolution

Reply via email to