{"id":21066,"date":"2018-04-03T11:15:33","date_gmt":"2018-04-03T15:15:33","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=21066"},"modified":"2018-04-03T11:15:33","modified_gmt":"2018-04-03T15:15:33","slug":"making-illegal-states-unrepresentable","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2018\/04\/03\/making-illegal-states-unrepresentable\/","title":{"rendered":"Making Illegal States Unrepresentable"},"content":{"rendered":"<p><a href=\"https:\/\/oleb.net\/blog\/2018\/03\/making-illegal-states-unrepresentable\/\">Ole Begemann<\/a> (<a href=\"https:\/\/twitter.com\/olebegemann\/status\/978284318836645893\">tweet<\/a>):<\/p>\n<blockquote cite=\"https:\/\/oleb.net\/blog\/2018\/03\/making-illegal-states-unrepresentable\/\"><p>The [<code>URLSession<\/code>] completion handler receives three optional values: <code>Data?<\/code>, <code>URLResponse?<\/code> and <code>Error?<\/code>. That makes 2&nbsp;&#xD7;&nbsp;2&nbsp;&#xD7;&nbsp;2&nbsp;=&nbsp;8 possible states, but how many of those are legal?<\/p>\n<p>[&#8230;]<\/p>\n<p>Brandon and Stephen made a small mistake: they assumed that the API will either return (a) a valid <code>Data<\/code> <em>and<\/em> <code>URLResponse<\/code>, <em>or<\/em> (b) an <code>Error<\/code>. After all, it shouldn&rsquo;t be possible to get a non-<code>nil<\/code> response and an error at the same time. Makes sense, right?<\/p>\n<p>It turns out that this is wrong. A <code>URLResponse<\/code> encapsulates the server&rsquo;s <a href=\"https:\/\/www.w3.org\/Protocols\/rfc2616\/rfc2616-sec6.html\">HTTP response headers<\/a>, and the <code>URLSession<\/code> API will always provide you with this value once it has received a valid response header, even if the request errors at a later stage (e.g. due to cancellation or a timeout). It&rsquo;s thus expected behavior for the completion handler to contain a populated <code>URLResponse<\/code> <em>and<\/em> a non-<code>nil<\/code> error value (but no <code>Data<\/code>).<\/p>\n<\/blockquote>","protected":false},"excerpt":{"rendered":"<p>Ole Begemann (tweet): The [URLSession] completion handler receives three optional values: Data?, URLResponse? and Error?. That makes 2&nbsp;&#xD7;&nbsp;2&nbsp;&#xD7;&nbsp;2&nbsp;=&nbsp;8 possible states, but how many of those are legal? [&#8230;] Brandon and Stephen made a small mistake: they assumed that the API will either return (a) a valid Data and URLResponse, or (b) an Error. After all, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"2018-04-12T01:13:07Z","apple_news_api_id":"f5f2601f-3f62-44d0-b489-fd35d010bfd9","apple_news_api_modified_at":"2018-04-12T01:13:07Z","apple_news_api_revision":"AAAAAAAAAAD\/\/\/\/\/\/\/\/\/\/w==","apple_news_api_share_url":"https:\/\/apple.news\/A9fJgHz9iRNC0if010BC_2Q","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[],"tags":[69,27,31,1472,30,1529,476,71,901,96],"class_list":["post-21066","post","type-post","status-publish","format-standard","hentry","tag-cocoa","tag-craft","tag-ios","tag-ios-11","tag-mac","tag-macos-10-13","tag-networking","tag-programming","tag-swift-programming-language","tag-web"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/21066","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=21066"}],"version-history":[{"count":1,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/21066\/revisions"}],"predecessor-version":[{"id":21067,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/21066\/revisions\/21067"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=21066"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=21066"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=21066"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}