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