<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="">Guh, second version should be this (Discourse save me).<div class=""><br class=""></div><div class="">enum&nbsp;MyError:&nbsp;Error&nbsp;{<br class="">&nbsp; &nbsp;&nbsp;<br class="">&nbsp; &nbsp;&nbsp;case&nbsp;network<br class="">&nbsp; &nbsp;&nbsp;case&nbsp;json<br class="">&nbsp; &nbsp;&nbsp;case&nbsp;value<br class="">&nbsp; &nbsp;&nbsp;<br class="">&nbsp; &nbsp;&nbsp;var&nbsp;localizedDescription:&nbsp;String&nbsp;{<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;switch&nbsp;self&nbsp;{<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;case&nbsp;.network:&nbsp;return&nbsp;"first"<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;case&nbsp;.json:&nbsp;return&nbsp;"second"<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;case&nbsp;.value:&nbsp;return&nbsp;"third"<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;}<br class="">&nbsp; &nbsp;&nbsp;}<br class="">&nbsp; &nbsp;&nbsp;<br class="">}<br class=""><br class="">extension&nbsp;MyError:&nbsp;LocalizedError&nbsp;{ }<br class=""><br class="">print((MyError.value&nbsp;as&nbsp;Error).localizedDescription)</div><div class=""><br class=""></div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Feb 28, 2017, at 4:36 PM, Jon Shier &lt;<a href="mailto:jon@jonshier.com" class="">jon@jonshier.com</a>&gt; 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="">Something strange I just observed. This version of MyError properly prints its localized description (in a Playground).&nbsp;<div class=""><br class=""></div><div class="">enum&nbsp;MyError:&nbsp;Error&nbsp;{<br class="">&nbsp; &nbsp;&nbsp;<br class="">&nbsp; &nbsp;&nbsp;case&nbsp;network<br class="">&nbsp; &nbsp;&nbsp;case&nbsp;json<br class="">&nbsp; &nbsp;&nbsp;case&nbsp;value<br class="">&nbsp; &nbsp;&nbsp;<br class="">&nbsp; &nbsp;&nbsp;var&nbsp;localizedDescription:&nbsp;String&nbsp;{<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;switch&nbsp;self&nbsp;{<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;case&nbsp;.network:&nbsp;return&nbsp;"first"<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;case&nbsp;.json:&nbsp;return&nbsp;"second"<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;case&nbsp;.value:&nbsp;return&nbsp;"third"<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;}<br class="">&nbsp; &nbsp;&nbsp;}<br class="">&nbsp; &nbsp;&nbsp;<br class="">&nbsp; &nbsp;&nbsp;var&nbsp;errorDescription:&nbsp;String? {&nbsp;return&nbsp;localizedDescription&nbsp;}<br class="">&nbsp; &nbsp;&nbsp;<br class="">}<br class=""><br class="">extension&nbsp;MyError:&nbsp;LocalizedError&nbsp;{ }<br class=""><br class="">print((MyError.value&nbsp;as&nbsp;Error).localizedDescription): third</div><div class=""><br class=""></div><div class="">However, this version does not:</div><div class=""><br class=""></div><div class="">enum&nbsp;MyError:&nbsp;Error&nbsp;{<br class="">&nbsp; &nbsp;&nbsp;<br class="">&nbsp; &nbsp;&nbsp;case&nbsp;network<br class="">&nbsp; &nbsp;&nbsp;case&nbsp;json<br class="">&nbsp; &nbsp;&nbsp;case&nbsp;value<br class="">&nbsp; &nbsp;&nbsp;<br class="">&nbsp; &nbsp;&nbsp;var&nbsp;localizedDescription:&nbsp;String&nbsp;{<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;switch&nbsp;self&nbsp;{<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;case&nbsp;.network:&nbsp;return&nbsp;"first"<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;case&nbsp;.json:&nbsp;return&nbsp;"second"<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;case&nbsp;.value:&nbsp;return&nbsp;"third"<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;}<br class="">&nbsp; &nbsp;&nbsp;}<br class="">&nbsp; &nbsp;&nbsp;<br class="">&nbsp; &nbsp;&nbsp;var&nbsp;errorDescription:&nbsp;String? {&nbsp;return&nbsp;localizedDescription&nbsp;}<br class="">&nbsp; &nbsp;&nbsp;<br class="">}<br class=""><br class="">extension&nbsp;MyError:&nbsp;LocalizedError&nbsp;{ }<br class=""><br class="">print((MyError.value&nbsp;as&nbsp;Error).localizedDescription):&nbsp;The operation couldn’t be completed. (__lldb_expr_103.MyError error 2.)</div><div class=""><br class=""></div><div class="">Surely that’s a bug?</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Jon</div><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Feb 28, 2017, at 4:32 PM, Jon Shier &lt;<a href="mailto:jon@jonshier.com" class="">jon@jonshier.com</a>&gt; 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="">Sorry, I forgot that part; MyError does conform to LocalizedError. However, even if it didn’t, Error has a localizedDescription property, so my question was why my implementation of that property wasn’t used in favor of the generated one. Or is that not the case for properties that aren’t required by the protocol? Even with the conformance, treating MyError as Error or LocalizedError doesn’t return the correct value for the property. localizedDescription seems to work fine when talking to Error instances backed by NSError though. This behavior doesn’t seem to be correct, otherwise there’s no way to get a useful description out of a custom Error without also implementing LocalizedError and treating the value as that type instead.<div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Jon</div><div class=""><br class=""></div><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Feb 28, 2017, at 4:10 PM, Jordan Rose &lt;<a href="mailto:jordan_rose@apple.com" class="">jordan_rose@apple.com</a>&gt; 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="" applecontenteditable="true"><div class="">'localizedDescription' isn't a requirement of the Error protocol, which means it's not a customization point. You need to actually conform to LocalizedError and provide a valid 'errorDescription' instead.</div><div class=""><br class=""></div><div class="">(It's too bad that your second test works at all, since MyError doesn't conform to LocalizedError. Unfortunately NSError <i class="">does</i>&nbsp;conform to LocalizedError, and all Errors can be bridged to NSError.)</div><div class=""><br class=""></div><div class="">If you're interested, you can find more information about the design in its proposal,&nbsp;<a href="https://github.com/apple/swift-evolution/blob/master/proposals/0112-nserror-bridging.md" class="">SE-0112</a>.</div><div class=""><br class=""></div><div class="">Hope this helps,</div><div class="">Jordan</div><div class=""><br class=""></div><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Feb 28, 2017, at 12:54, Jon Shier via swift-users &lt;<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Swifters:<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>I have a custom error enum:<br class=""><br class="">enum MyError: Error {<br class=""><br class=""> &nbsp;&nbsp;&nbsp;case network(error: Error)<br class=""> &nbsp;&nbsp;&nbsp;case json(error: Error)<br class=""> &nbsp;&nbsp;&nbsp;case value(error: Error)<br class=""><br class=""> &nbsp;&nbsp;&nbsp;var localizedDescription: String {<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch self {<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case let .network(error): return error.localizedDescription<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case let .json(error): return error.localizedDescription<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case let .value(error): return error.localizedDescription<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br class=""> &nbsp;&nbsp;&nbsp;}<br class=""><br class="">}<br class=""><br class="">However, the localizedDescription output is odd to me. When the value is treated as:<br class=""><br class="">Error: &nbsp;po error.localizedDescription<br class="">"The operation couldn’t be completed. (MyApp.MyError error 1.)”<br class=""><br class="">LocalizedError: &nbsp;po (error as! LocalizedError).localizedDescription<br class="">"The operation couldn’t be completed. (MyApp.MyError error 1.)”<br class=""><br class="">MyError: Error: &nbsp;po (error as! MyError).localizedDescription<br class="">"JSON could not be serialized because of error:\nThe data couldn’t be read because it isn’t in the correct format."<br class=""><br class="">Shouldn’t my implementation of localizedDescription take precedence in all cases here? (This is Xcode 8.3b3).<br class=""><br class=""><br class=""><br class="">Jon<br class="">_______________________________________________<br class="">swift-users mailing list<br class=""><a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-users" class="">https://lists.swift.org/mailman/listinfo/swift-users</a><br class=""></div></div></blockquote></div><br class=""></div></div></blockquote></div><br class=""></div></div></div></blockquote></div><br class=""></div></div></div></blockquote></div><br class=""></div></body></html>