{"action":"closed","issue":{"url":"https://api.github.com/repos/golang/go/issues/12866","labels_url":"https://api.github.com/repos/golang/go/issues/12866/labels{/name}","comments_url":"https://api.github.com/repos/golang/go/issues/12866/comments","events_url":"https://api.github.com/repos/golang/go/issues/12866/events","html_url":"https://github.com/golang/go/issues/12866","id":110263383,"number":12866,"title":"net/url: url.Error should propagate the net.Error interface","user":{"login":"jum","id":33510,"avatar_url":"https://avatars.githubusercontent.com/u/33510?v=3","gravatar_id":"","url":"https://api.github.com/users/jum","html_url":"https://github.com/jum","followers_url":"https://api.github.com/users/jum/followers","following_url":"https://api.github.com/users/jum/following{/other_user}","gists_url":"https://api.github.com/users/jum/gists{/gist_id}","starred_url":"https://api.github.com/users/jum/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jum/subscriptions","organizations_url":"https://api.github.com/users/jum/orgs","repos_url":"https://api.github.com/users/jum/repos","events_url":"https://api.github.com/users/jum/events{/privacy}","received_events_url":"https://api.github.com/users/jum/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":{"login":"davecheney","id":7171,"avatar_url":"https://avatars.githubusercontent.com/u/7171?v=3","gravatar_id":"","url":"https://api.github.com/users/davecheney","html_url":"https://github.com/davecheney","followers_url":"https://api.github.com/users/davecheney/followers","following_url":"https://api.github.com/users/davecheney/following{/other_user}","gists_url":"https://api.github.com/users/davecheney/gists{/gist_id}","starred_url":"https://api.github.com/users/davecheney/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davecheney/subscriptions","organizations_url":"https://api.github.com/users/davecheney/orgs","repos_url":"https://api.github.com/users/davecheney/repos","events_url":"https://api.github.com/users/davecheney/events{/privacy}","received_events_url":"https://api.github.com/users/davecheney/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/golang/go/milestones/24","html_url":"https://github.com/golang/go/milestones/Go1.6","labels_url":"https://api.github.com/repos/golang/go/milestones/24/labels","id":1096159,"number":24,"title":"Go1.6","description":"","creator":{"login":"josharian","id":67496,"avatar_url":"https://avatars.githubusercontent.com/u/67496?v=3","gravatar_id":"","url":"https://api.github.com/users/josharian","html_url":"https://github.com/josharian","followers_url":"https://api.github.com/users/josharian/followers","following_url":"https://api.github.com/users/josharian/following{/other_user}","gists_url":"https://api.github.com/users/josharian/gists{/gist_id}","starred_url":"https://api.github.com/users/josharian/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/josharian/subscriptions","organizations_url":"https://api.github.com/users/josharian/orgs","repos_url":"https://api.github.com/users/josharian/repos","events_url":"https://api.github.com/users/josharian/events{/privacy}","received_events_url":"https://api.github.com/users/josharian/received_events","type":"User","site_admin":false},"open_issues":329,"closed_issues":180,"state":"open","created_at":"2015-05-05T02:39:06Z","updated_at":"2015-10-10T11:33:18Z","due_on":"2016-01-31T08:00:00Z","closed_at":null},"comments":7,"created_at":"2015-10-07T16:21:47Z","updated_at":"2015-10-10T11:33:18Z","closed_at":"2015-10-10T11:33:18Z","body":"At some points in a program it might interesting to find out if a network error is transient or a timeout. If the program uses Dial et. al. this is handled by calling the Temporary() or Timeout() interfaces on net.Error. But if the program uses http.Get or similar, the net.Error is hidden behind url.Error.Err. one has to use a logic like this check for transient errors:\r\n\r\n\t\t\t\ttestErr := err\r\n\t\t\t\tif e, ok := testErr.(*url.Error); ok {\r\n\t\t\t\t\ttestErr = e.Err\r\n\t\t\t\t}\r\n\t\t\t\t// As we are called regularly by cron, ignore some errors.\r\n\t\t\t\ttype timeout interface {\r\n\t\t\t\t\tTimeout() bool\r\n\t\t\t\t}\r\n\t\t\t\tif e, ok := testErr.(timeout); ok {\r\n\t\t\t\t\tif e.Timeout() {\r\n\t\t\t\t\t\terr = nil\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\ttype temporary interface {\r\n\t\t\t\t\tTemporary() bool\r\n\t\t\t\t}\r\n\t\t\t\tif e, ok := testErr.(temporary); ok {\r\n\t\t\t\t\tif e.Temporary() {\r\n\t\t\t\t\t\terr = nil\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\nIf url.Error would embed Err anonymously, any interfaces would be available without the type assertion to *url.Error."}}