{"action":"created","issue":{"url":"https://api.github.com/repos/dart-lang/sdk/issues/34144","repository_url":"https://api.github.com/repos/dart-lang/sdk","labels_url":"https://api.github.com/repos/dart-lang/sdk/issues/34144/labels{/name}","comments_url":"https://api.github.com/repos/dart-lang/sdk/issues/34144/comments","events_url":"https://api.github.com/repos/dart-lang/sdk/issues/34144/events","html_url":"https://github.com/dart-lang/sdk/issues/34144","id":350542937,"node_id":"MDU6SXNzdWUzNTA1NDI5Mzc=","number":34144,"title":"Future.catchError is error prone","user":{"login":"matanlurey","id":168174,"node_id":"MDQ6VXNlcjE2ODE3NA==","avatar_url":"https://avatars2.githubusercontent.com/u/168174?v=4","gravatar_id":"","url":"https://api.github.com/users/matanlurey","html_url":"https://github.com/matanlurey","followers_url":"https://api.github.com/users/matanlurey/followers","following_url":"https://api.github.com/users/matanlurey/following{/other_user}","gists_url":"https://api.github.com/users/matanlurey/gists{/gist_id}","starred_url":"https://api.github.com/users/matanlurey/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matanlurey/subscriptions","organizations_url":"https://api.github.com/users/matanlurey/orgs","repos_url":"https://api.github.com/users/matanlurey/repos","events_url":"https://api.github.com/users/matanlurey/events{/privacy}","received_events_url":"https://api.github.com/users/matanlurey/received_events","type":"User","site_admin":false},"labels":[{"id":219928184,"node_id":"MDU6TGFiZWwyMTk5MjgxODQ=","url":"https://api.github.com/repos/dart-lang/sdk/labels/area-library","name":"area-library","color":"c7def8","default":false},{"id":265663677,"node_id":"MDU6TGFiZWwyNjU2NjM2Nzc=","url":"https://api.github.com/repos/dart-lang/sdk/labels/customer-flutter","name":"customer-flutter","color":"006b75","default":false},{"id":437839480,"node_id":"MDU6TGFiZWw0Mzc4Mzk0ODA=","url":"https://api.github.com/repos/dart-lang/sdk/labels/customer-google3","name":"customer-google3","color":"006b75","default":false},{"id":219928158,"node_id":"MDU6TGFiZWwyMTk5MjgxNTg=","url":"https://api.github.com/repos/dart-lang/sdk/labels/p1-high","name":"p1-high","color":"eb6420","default":false},{"id":334529267,"node_id":"MDU6TGFiZWwzMzQ1MjkyNjc=","url":"https://api.github.com/repos/dart-lang/sdk/labels/type-enhancement","name":"type-enhancement","color":"ededed","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":14,"created_at":"2018-08-14T18:22:55Z","updated_at":"2018-08-30T20:14:14Z","closed_at":null,"author_association":"CONTRIBUTOR","body":"(Forked from an _internal_ thread; @munificent and others have additional context)\r\n\r\n> I noticed in code reviews that developers often do:\r\n> `return someFuture.catchError((e) => log(...));`\r\n> \r\n> But this pattern actually swallows the error, and instead propagates a null to the caller, which may cause an NPE or worse down the future chain. This pattern is only good if catchError returned future is a terminal (=\"orphaned\") future (which is often an error-prone pattern too).\r\n\r\n@munificent writes, in response:\r\n\r\n> In most cases, the easy fix is to avoid using catchError() at all and use async/await instead. That way, you can use a regular catch clause where people (hopefully!) already know how to log and rethrow exceptions correctly.\r\n\r\n>> Compare with Java Futures, which doesn't have his errorprone pattern, because its catching function takes a Function<?, V>, not Function, and in Java, and the void output of print would not match with V.\r\n\r\n> We can't do that in Dart because catchError() accepts either of two kinds of functions: a single-parameter function that just accepts the error, or a two-parameter one that accepts the error and stack trace. We don't have overloading in Dart, so we have to loosen catchError()'s parameter type to Function to accept both kinds.\r\n\r\n> (Java, of course, doesn't have this problem because it puts the stack trace directly on the exception object instead of passing it around separately.)\r\n\r\n-----\r\n\r\nYou can see a minimal example of this problem in action in the following code sample:\r\n\r\n```dart\r\nvoid main() {\r\n  invokeLazy(() => aVoidMethod());\r\n}\r\n\r\n// We need this to actually return a String, but we can't specify the type due to lack of overloads.\r\n// See https://api.dartlang.org/stable/2.0.0/dart-async/Future/catchError.html.\r\nvoid invokeLazy(Function aString) {\r\n  print(aString);\r\n}\r\n\r\nvoid aVoidMethod() {}\r\n```\r\n\r\nAPI reference for `<Future>.catchError`:\r\nhttps://api.dartlang.org/stable/2.0.0/dart-async/Future/catchError.html\r\n\r\n**EDIT**: I believe there is another bug, somewhere, about the hidden errors you get if you write:\r\n\r\n```dart\r\n// (ArgumentError) => void is not a (dynamic) => dynamic.\r\nfuture.catchError((ArgumentError e) => ...);\r\n```"},"comment":{"url":"https://api.github.com/repos/dart-lang/sdk/issues/comments/417452422","html_url":"https://github.com/dart-lang/sdk/issues/34144#issuecomment-417452422","issue_url":"https://api.github.com/repos/dart-lang/sdk/issues/34144","id":417452422,"node_id":"MDEyOklzc3VlQ29tbWVudDQxNzQ1MjQyMg==","user":{"login":"natebosch","id":7528195,"node_id":"MDQ6VXNlcjc1MjgxOTU=","avatar_url":"https://avatars3.githubusercontent.com/u/7528195?v=4","gravatar_id":"","url":"https://api.github.com/users/natebosch","html_url":"https://github.com/natebosch","followers_url":"https://api.github.com/users/natebosch/followers","following_url":"https://api.github.com/users/natebosch/following{/other_user}","gists_url":"https://api.github.com/users/natebosch/gists{/gist_id}","starred_url":"https://api.github.com/users/natebosch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/natebosch/subscriptions","organizations_url":"https://api.github.com/users/natebosch/orgs","repos_url":"https://api.github.com/users/natebosch/repos","events_url":"https://api.github.com/users/natebosch/events{/privacy}","received_events_url":"https://api.github.com/users/natebosch/received_events","type":"User","site_admin":false},"created_at":"2018-08-30T20:14:14Z","updated_at":"2018-08-30T20:14:14Z","author_association":"MEMBER","body":"> An analyzer special-case is a much more promising.\r\n\r\nIn my opinion this should be our focus. @bwilkerson - can you weigh in on the feasibility?"}}
{"actor":{"display_login":"natebosch"}}