<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=""><br class=""><div><blockquote type="cite" class=""><div class="">On Feb 27, 2017, at 1:46 PM, David Waite 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=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">IMHO, there are two kinds of responses to errors - a specific response, and a general one. Only the calling code knows how it will deal with errors, so a “typed throws” is the function guessing possible calling code behavior.</div><div class=""><br class=""></div><div class="">The problem is, that gives four possible combinations - two where the function guesses correctly, and two where it doesn’t. The most damaging is when it suspects a caller doesn’t care about the error, when the caller actually does. This is unwanted wrapping.</div><div class=""><br class=""></div><div class="">To provide an example, imagine a library that parses JSON. It has several errors indicating JSON syntactic errors, and an “other” for representing errors on the input stream. It wraps the input stream errors so that it can provide a closed set of errors to the caller.</div><div class=""><br class=""></div><div class="">The caller is responsible for returning a data set. It doesn’t think that code calling ‘it” cares about JSON syntactic errors, merely that the object was not able to be restored. It returns its own wrapped error.</div><div class=""><br class=""></div><div class="">However, the original caller knows it is loading from disk. If the problem is due to an issue such as access permissions, It has to know implementation details of the API it called if it wishes to dive through the wrapped errors to find out if the problem was filesystem related.</div></div></div></blockquote><div><br class=""></div><div>On the other hand, without wrapping the caller still needs to know the implementation details of the API in order to know what errors its dependencies might throw and the burden of grouping errors into higher-level categories is punted to the caller. Some callers might appreciate the directness and specificity of the original error but many others might appreciate the higher level grouping.</div><div><br class=""></div><div>This is ultimately a question of API design where there is no one right answer.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">Add more layers, and it can be very mysterious why a call failed. Java at least captures stack traces in this case to aid in technical support in diagnosing the error.</div><div class=""><br class=""></div><div class="">Wrapping exceptions also prevents an aggregate of errors from different subsystems being handled as a category, such as having a catch block handle RecoverableError generically</div></div></div></blockquote><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">An interesting solution that has emerged in Ruby to keep library authors from wrapping exceptions is by decorating the existing exception. Exceptions are caught via pattern matching (same as in Swift), so rather than wrap an extension, they extend the error instance with a library-specific module (e.g. swift protocol). So while the error may be a IOError in ruby, you can still catch it via ‘rescue JSONError’</div></div></div></blockquote><div><br class=""></div><div>If I understand this correctly it sounds like introducing a library would create protocols to categorize errors and add retroactive conformances to these protocols for errors thrown by its dependencies? That is an interesting approach. But it requires knowing the concrete types of the possible errors all the way down the stack (you can’t add a conformance to an existential). This seems very problematic to me, especially in a language where creating new error types is as easy as it is in Swift.</div><div><br class=""></div><div>Error handling is messy, there’s no doubt about that. I would like to have as many tools at my disposal as possible. Error types is one of those tools.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">Trying to specify the exact errors becomes even more destructive with protocols and closures, where the person defining the interface knows neither which errors the implementor of the call will throw, nor necessarily if the caller will want to implement specific behavior on those errors. This in my personal Java coding experience almost always leads to wrapping in some protocol-specific Exception type which exposes minimal information to the caller, or exposing your errors in some unrelated type like IOException which was declared based on the author’s experience of possible exceptions.</div></div></div></blockquote><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">-DW</div><div class=""> </div><div class=""><div class=""><blockquote type="cite" class=""><div class="">On Feb 27, 2017, at 5:19 AM, Daniel Leping 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 class=""><br class=""><div class="gmail_quote"><div class="">On Mon, 27 Feb 2017 at 8:44 Dave Abrahams via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br class="gmail_msg">
on Fri Feb 17 2017, Joe Groff <<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>> wrote:<br class="gmail_msg">
<br class="gmail_msg">
> Experience in other languages like Rust and Haskell that use<br class="gmail_msg">
> Result-based error propagation suggests that a single error type is<br class="gmail_msg">
> adequate, and beneficial in many ways.</blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br class="gmail_msg">
<br class="gmail_msg">
And experience in still others, like C++ and Java, suggests that<br class="gmail_msg">
using static types to restrict the kind of information a function can<br class="gmail_msg">
give you when an error occurs may actually be harmful.</blockquote><div class="">+1 here. It becomes wrapping over wrapping over wrapping. Try doing a big app in Java (i.e. some kind of layered server) and you'll understand everything. Ones who tried and still want it - well, there are different tastes out there.</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br class="gmail_msg">
<br class="gmail_msg">
--<br class="gmail_msg">
-Dave<br class="gmail_msg">
<br class="gmail_msg">
_______________________________________________<br class="gmail_msg">
swift-evolution mailing list<br class="gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg">
</blockquote></div></div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>