> On 27 Dec 2016, at 13:21, Haravikk <[email protected]> wrote:
> 
> 
>> On 27 Dec 2016, at 10:56, Derrick Ho via swift-evolution 
>> <[email protected] <mailto:[email protected]>> wrote:
>> 
>> Daniel Leping, I am unfamiliar with java. Do you have any resources that 
>> describe the nightmare in detail?
> 
> I think the problem really comes down to the inflexibility of it; if you 
> specify X, Y, and Z as throwable types, then all code calling that method 
> must handle those types in some way.
> 
> Thing is, I wonder if this would be as much of a problem for Swift? We have 
> the try! and try? variations which make it very easy to ignore/simplify error 
> handling if we don't expect any to occur at all, or it doesn't matter if they 
> do, and we have the same basic means of handling generic unknown (or 
> unhandled) error types, plus throws and rethrows.
> 
> Part of the problem is that Java only ever treats the specified types as 
> mandatory (you *must* handle them somehow); I think a more elegant solution 
> could be if we could somehow mark them as optional, for example:
> 
>       func myMethod(args:[String:Any]) throws IOError, IllegalArgumentError? 
> { … }
> 
> Here myMethod can throw two error types, IOError and IllegalArgumentError, 
> but while the first *must* be handled somehow, the latter is only optional as 
> a well formed args dictionary cannot possibly produce an error, i.e- it's an 
> error you might only want to check if the args dictionary was built 
> dynamically.
> 
> Basically in this case not handling an IOError would be an error, while not 
> handling IllegalArgumentError would be a warning (with some way to suppress 
> it). This means that APIs could even add new error types so long as they are 
> optional, though it's not advisable.
> 
> In addition to this we might introduce some mechanism for specifying *some* 
> of a method's error types, for example:
> 
>       func myMethod() throws IOError… { … }
> 
> Here myMethod specifies an explicit IOError that *must* be handled, but also 
> indicates that there are other, optional, types that don't need to be handled 
> explicitly. The idea here is that you specify only the most important types, 
> but can still indicate that there are other possible types (but maybe they're 
> rare, or only occur in very unusual circumstances described in 
> documentation), or you just want to leave the definition open-ended.
> 
> So yeah; personally I'm a supporter of being *able* to specify thrown types, 
> but do think it needs to be more flexible in what and how we specify them, to 
> avoid falling into the same pitfalls as Java. I definitely think that being 
> able to specify types that *must* be handled is useful, though we'd need to 
> make clear best practice (i.e- mandatory type handling should be reserved for 
> more serious errors in most cases).
> 
> Other things to consider are wether explicit thrown types could be marked as 
> handle immediately (i.e- throwing the error up the chain is a warning), and 
> whether non-explicit throws/rethrows could be automatically computed. For 
> example, if I have a method that has a plain throws, and handles three 
> methods, throwing errors of A, B? and C… respectively, with the first called 
> via try?, then my method's throwable types are B?, C…
> 
> 
> To conclude; while I like Swift's error handling as-is it's mostly because I 
> tend to use try! and try?, but when it comes to an actual try/catch I do like 
> Java's compiler supported enforcement making sure that I'm aware of which 
> types I'm supposed to do something with.


This is why I think a comment-based system would be better. You can have long 
lists which describe every error case in detail and what to do about it, 
without cluttering the function signature. 

Describe a single error:

/// - throws:
///     - POSIXError.EBADF: the descriptor is invalid

Describe a whole enum-full of error cases:

/// - throws:
///     - POSIXError.EBADF: the descriptor is invalid
///     - ReadError: the read operation failed

Maybe make it an exhaustive list with “throws only”:

/// - throws only:
///     - POSIXError.EBADF: the descriptor is invalid
///     - ReadError: the read operation failed

Or maybe we will consider them all to be exhaustive by default, but allow 
adding a wildcard item to indicate otherwise:

/// - throws:
///     - POSIXError.EBADF: the descriptor is invalid
///     - ReadError: the read operation failed
///     - *

We could also use that documentation for quick-help popups on catch statements. 
IDE-generated do/catch blocks could include comments to help you fill in the 
details:

do {
    try readFile()
}
catch error as POSIXError.EBADF {
    // the descriptor is invalid
    [<code>]
}
catch error as ReadError {
    // the read operation failed
    [<code>]
}

- Karl
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to