{"action":"created","issue":{"url":"https://api.github.com/repos/golang/go/issues/21161","repository_url":"https://api.github.com/repos/golang/go","labels_url":"https://api.github.com/repos/golang/go/issues/21161/labels{/name}","comments_url":"https://api.github.com/repos/golang/go/issues/21161/comments","events_url":"https://api.github.com/repos/golang/go/issues/21161/events","html_url":"https://github.com/golang/go/issues/21161","id":245467015,"node_id":"MDU6SXNzdWUyNDU0NjcwMTU=","number":21161,"title":"proposal: Go 2: simplify error handling with || err suffix","user":{"login":"ianlancetaylor","id":3194333,"node_id":"MDQ6VXNlcjMxOTQzMzM=","avatar_url":"https://avatars2.githubusercontent.com/u/3194333?v=4","gravatar_id":"","url":"https://api.github.com/users/ianlancetaylor","html_url":"https://github.com/ianlancetaylor","followers_url":"https://api.github.com/users/ianlancetaylor/followers","following_url":"https://api.github.com/users/ianlancetaylor/following{/other_user}","gists_url":"https://api.github.com/users/ianlancetaylor/gists{/gist_id}","starred_url":"https://api.github.com/users/ianlancetaylor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ianlancetaylor/subscriptions","organizations_url":"https://api.github.com/users/ianlancetaylor/orgs","repos_url":"https://api.github.com/users/ianlancetaylor/repos","events_url":"https://api.github.com/users/ianlancetaylor/events{/privacy}","received_events_url":"https://api.github.com/users/ianlancetaylor/received_events","type":"User","site_admin":false},"labels":[{"id":150880249,"node_id":"MDU6TGFiZWwxNTA4ODAyNDk=","url":"https://api.github.com/repos/golang/go/labels/Go2","name":"Go2","color":"ffaaaa","default":false},{"id":150880200,"node_id":"MDU6TGFiZWwxNTA4ODAyMDA=","url":"https://api.github.com/repos/golang/go/labels/LanguageChange","name":"LanguageChange","color":"ffaaaa","default":false},{"id":373402289,"node_id":"MDU6TGFiZWwzNzM0MDIyODk=","url":"https://api.github.com/repos/golang/go/labels/NeedsInvestigation","name":"NeedsInvestigation","color":"ededed","default":false},{"id":236419512,"node_id":"MDU6TGFiZWwyMzY0MTk1MTI=","url":"https://api.github.com/repos/golang/go/labels/Proposal","name":"Proposal","color":"ededed","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/golang/go/milestones/30","html_url":"https://github.com/golang/go/milestone/30","labels_url":"https://api.github.com/repos/golang/go/milestones/30/labels","id":1373555,"node_id":"MDk6TWlsZXN0b25lMTM3MzU1NQ==","number":30,"title":"Proposal","description":"Proposals that are pending (not yet accepted/rejected).\r\n","creator":{"login":"rsc","id":104030,"node_id":"MDQ6VXNlcjEwNDAzMA==","avatar_url":"https://avatars1.githubusercontent.com/u/104030?v=4","gravatar_id":"","url":"https://api.github.com/users/rsc","html_url":"https://github.com/rsc","followers_url":"https://api.github.com/users/rsc/followers","following_url":"https://api.github.com/users/rsc/following{/other_user}","gists_url":"https://api.github.com/users/rsc/gists{/gist_id}","starred_url":"https://api.github.com/users/rsc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rsc/subscriptions","organizations_url":"https://api.github.com/users/rsc/orgs","repos_url":"https://api.github.com/users/rsc/repos","events_url":"https://api.github.com/users/rsc/events{/privacy}","received_events_url":"https://api.github.com/users/rsc/received_events","type":"User","site_admin":false},"open_issues":209,"closed_issues":526,"state":"open","created_at":"2015-10-24T01:40:49Z","updated_at":"2018-06-14T07:21:13Z","due_on":null,"closed_at":null},"comments":447,"created_at":"2017-07-25T16:54:58Z","updated_at":"2018-06-14T11:51:49Z","closed_at":null,"author_association":"CONTRIBUTOR","body":"There have been many proposals for how to simplify error handling in Go, all based on the general complaint that too much Go code contains the lines\r\n\r\n```\r\nif err != nil {\r\n    return err\r\n}\r\n```\r\n\r\nI'm not sure that there is a problem here to be solved, but since it keeps coming up, I'm going to put out this idea.\r\n\r\nOne of the core problems with most suggestions for simplifying error handling is that they only simplify two ways of handling errors, but there are actually three:\r\n\r\n1. ignore the error\r\n2. return the error unmodified\r\n3. return the error with additional contextual information\r\n\r\nIt is already easy (perhaps too easy) to ignore the error (see #20803).  Many existing proposals for error handling make it easier to return the error unmodified (e.g., #16225, #18721, #21146, #21155).  Few make it easier to return the error with additional information.\r\n\r\nThis proposal is loosely based on the Perl and Bourne shell languages, fertile sources of language ideas.  We introduce a new kind of statement, similar to an expression statement: a call expression followed by `||`.  The grammar is:\r\n\r\n    PrimaryExpr Arguments \"||\" Expression\r\n\r\nSimilarly we introduce a new kind of assignment statement:\r\n\r\n    ExpressionList assign_op PrimaryExpr Arguments \"||\" Expression\r\n\r\nAlthough the grammar accepts any type after the `||` in the non-assignment case, the only permitted type is the predeclared type `error`.  The expression following `||` must have a type assignable to `error`.  It may not be a boolean type, not even a named boolean type assignable to `error`.  (This latter restriction is required to make this proposal backward compatible with the existing language.)\r\n\r\nThese new kinds of statement is only permitted in the body of a function that has at least one result parameter, and the type of the last result parameter must be the predeclared type `error`.  The function being called must similarly have at least one result parameter, and the type of the last result parameter must be the predeclared type `error`.\r\n\r\nWhen executing these statements, the call expression is evaluated as usual.  If it is an assignment statement, the call results are assigned to the left-hand side operands as usual.  Then the last call result, which as described above must be of type `error`, is compared to `nil`.  If the last call result is not `nil`, a return statement is implicitly executed.  If the calling function has multiple results, the zero value is returned for all result but the last one.  The expression following the `||` is returned as the last result.  As described above, the last result of the calling function must have type `error`, and the expression must be assignable to type `error`.\r\n\r\nIn the non-assignment case, the expression is evaluated in a scope in which a new variable `err` is introduced and set to the value of the last result of the function call.  This permits the expression to easily refer to the error returned by the call.  In the assignment case, the expression is evaluated in the scope of the results of the call, and thus can refer to the error directly.\r\n\r\nThat is the complete proposal.\r\n\r\nFor example, the `os.Chdir` function is currently\r\n\r\n```\r\nfunc Chdir(dir string) error {\r\n\tif e := syscall.Chdir(dir); e != nil {\r\n\t\treturn &PathError{\"chdir\", dir, e}\r\n\t}\r\n\treturn nil\r\n}\r\n```\r\n\r\nUnder this proposal, it could be written as\r\n\r\n```\r\nfunc Chdir(dir string) error {\r\n\tsyscall.Chdir(dir) || &PathError{\"chdir\", dir, err}\r\n\treturn nil\r\n}\r\n```\r\n\r\nI'm writing this proposal mainly to encourage people who want to simplify Go error handling to think about ways to make it easy to wrap context around errors, not just to return the error unmodified."},"comment":{"url":"https://api.github.com/repos/golang/go/issues/comments/397267440","html_url":"https://github.com/golang/go/issues/21161#issuecomment-397267440","issue_url":"https://api.github.com/repos/golang/go/issues/21161","id":397267440,"node_id":"MDEyOklzc3VlQ29tbWVudDM5NzI2NzQ0MA==","user":{"login":"urandom","id":7908,"node_id":"MDQ6VXNlcjc5MDg=","avatar_url":"https://avatars2.githubusercontent.com/u/7908?v=4","gravatar_id":"","url":"https://api.github.com/users/urandom","html_url":"https://github.com/urandom","followers_url":"https://api.github.com/users/urandom/followers","following_url":"https://api.github.com/users/urandom/following{/other_user}","gists_url":"https://api.github.com/users/urandom/gists{/gist_id}","starred_url":"https://api.github.com/users/urandom/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/urandom/subscriptions","organizations_url":"https://api.github.com/users/urandom/orgs","repos_url":"https://api.github.com/users/urandom/repos","events_url":"https://api.github.com/users/urandom/events{/privacy}","received_events_url":"https://api.github.com/users/urandom/received_events","type":"User","site_admin":false},"created_at":"2018-06-14T11:51:49Z","updated_at":"2018-06-14T11:51:49Z","author_association":"NONE","body":"@egorse \r\nIt seems the try-catch syntax @KamyarM is suggesting is some syntax sugar for handling error return variables, not an introduction for exceptions. While I prefer an \"or return\" type syntax for various reasons, it does seem like a legit suggestion.\r\n\r\nThat being said, @KamyarM , why does the `try` have a variable definition portion in it? You are defining an `err` variable, but its being shadowed by the other `err` variables within the block itself. What is its purpose?"}}
{"actor":{"display_login":"urandom"}}