<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div class="">On Mar 14, 2016, at 10:20 AM, Maximilian Hünenberger via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="auto" class=""><div class=""></div><div class="">How about only allowing "guard try? catch":</div><div class=""><br class=""></div><div class=""> guard let x = try? foo() catch { ... }</div><div class=""><br class=""></div><div class="">This would address both concerns of Chris:</div><div class=""><br class=""></div><div class="">• "<span class="" style="background-color: rgba(255, 255, 255, 0);">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."</span></div><div class=""><span class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div><div class=""><span class="" style="background-color: rgba(255, 255, 255, 0);">• "This shouldn’t be tied to the presence of try, because it already means something (that the enclosed expression can throw). This:</span></div><div class=""><span class="" style="background-color: rgba(255, 255, 255, 0);"> guard let x = try foo() …</span></div><div class=""><span class="" style="background-color: rgba(255, 255, 255, 0);">Already means “call foo, if it throws, propagate the error. If not, test the returned optional”."</span></div><div class=""><span class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div><div class=""><span class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div><div class=""><span class="" style="background-color: rgba(255, 255, 255, 0);">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.</span></div><div class=""><span class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div><div class=""><span class="" style="background-color: rgba(255, 255, 255, 0);">Kind regards</span></div><div class=""><span class="" style="background-color: rgba(255, 255, 255, 0);">- Maximilian</span></div></div></div></blockquote></div><div class=""><div class=""><div dir="auto" class=""><div class=""><span class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div><div class=""><span class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div></div></div></div><div class="">I'm not a fan of the notion of guard/catch. However, it occurs to me that my "attempt" code may address this issue.</div><div class="">I've recently updated it to take an arbitrary error handler, which if omitted, simply prints the error. Otherwise it acts like try?</div><div class="">or if you set crashOnError, like try!. It works with guard.</div><div class=""><br class=""></div><div class="">-- E</div><div class=""><br class=""></div><div class=""><div class="">github: <a href="https://github.com/erica/SwiftUtility/blob/master/Sources/CoreError.swift" class="">https://github.com/erica/SwiftUtility/blob/master/Sources/CoreError.swift</a></div></div><div class=""><br class=""></div><div class=""><pre style="word-wrap: break-word; white-space: pre-wrap;" class="">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
}
}
</pre></div><div class=""><br class=""></div><br class=""></body></html>