{"action":"created","comment":{"url":"https://api.github.com/repos/google/error-prone/pulls/comments/45003323","id":45003323,"diff_hunk":"@@ -0,0 +1,389 @@\n+/*\n+ * Copyright 2013 Google Inc. All Rights Reserved.\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \"License\");\n+ * you may not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at\n+ *\n+ *     http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+\n+package com.google.errorprone.bugpatterns;\n+\n+import static com.google.errorprone.BugPattern.Category.JDK;\n+import static com.google.errorprone.BugPattern.MaturityLevel.MATURE;\n+import static com.google.errorprone.BugPattern.SeverityLevel.ERROR;\n+import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;\n+\n+import com.google.errorprone.BugPattern;\n+import com.google.errorprone.VisitorState;\n+import com.google.errorprone.bugpatterns.BugChecker.TryTreeMatcher;\n+import com.google.errorprone.fixes.SuggestedFix;\n+import com.google.errorprone.matchers.Description;\n+import com.google.errorprone.util.ASTHelpers;\n+import com.sun.source.tree.LineMap;\n+\n+import static com.sun.source.tree.Tree.Kind;\n+import static com.sun.source.tree.Tree.Kind.RETURN;\n+import static com.sun.source.tree.Tree.Kind.CONTINUE;\n+import static com.sun.source.tree.Tree.Kind.BREAK;\n+import static com.sun.source.tree.Tree.Kind.ASSIGNMENT;\n+import static com.sun.source.tree.Tree.Kind.EXPRESSION_STATEMENT;\n+import static com.sun.source.tree.Tree.Kind.EMPTY_STATEMENT;\n+import static com.sun.source.tree.Tree.Kind.CATCH;\n+import static com.sun.source.tree.Tree.Kind.BLOCK;\n+import static com.sun.source.tree.Tree.Kind.IF;\n+import static com.sun.source.tree.Tree.Kind.FOR_LOOP;\n+import static com.sun.source.tree.Tree.Kind.DO_WHILE_LOOP;\n+import static com.sun.source.tree.Tree.Kind.WHILE_LOOP;\n+import static com.sun.source.tree.Tree.Kind.ENHANCED_FOR_LOOP;\n+import static com.sun.source.tree.Tree.Kind.SWITCH;\n+import static com.sun.source.tree.Tree.Kind.TRY;\n+import static com.sun.source.tree.Tree.Kind.VARIABLE;\n+\n+import com.sun.source.tree.MethodTree;\n+import com.sun.source.tree.CatchTree;\n+import com.sun.source.tree.StatementTree;\n+import com.sun.source.tree.TryTree;\n+import com.sun.source.tree.BlockTree;\n+import com.sun.source.tree.ExpressionTree;\n+import com.sun.source.tree.ExpressionStatementTree;\n+\n+import com.sun.source.util.TreePath;\n+import com.sun.tools.javac.code.Symbol;\n+import com.sun.tools.javac.code.Symbol.MethodSymbol;\n+import com.sun.tools.javac.tree.JCTree;\n+import com.sun.tools.javac.tree.TreeInfo;\n+\n+import java.util.List;\n+\n+/**\n+ * A bug checker for empty exception handling block:\n+ *\n+ * <pre>\n+ * try {\n+ *   // do something\n+ * } catch (XX e) {\n+ *   // empty, only comment, or only log printing statements\n+ * }\n+ * </pre>\n+ * We also implement a variety of false positive suppression heuristics.\n+ * \n+ * For more detail, refer to the paper:\n+ * \"Simple Testing Can Prevent Most Critical Failures: \n+ *  An Analysis of Production Failures in Distributed Data-intensive Systems\"\n+ *  Yuan et al. Proceedings of the 11th USENIX Symposium on Operating Systems Design \n+ *  and Implementation (OSDI), 2014\n+ *\n+ * @author yuan@eecg.utoronto.ca (Ding Yuan)\n+ */\n+@BugPattern(name = \"EmptyCatch\",\n+    summary = \"Empty catch blocks that ignore exceptions\",\n+    explanation = \"Ignoring exception is a bad practice.\",\n+    category = JDK, maturity = MATURE, severity = WARNING)\n+public class EmptyCatch extends BugChecker implements TryTreeMatcher {\n+  /* If one of the following exceptions is ignored, we suppress the warning. */\n+  String[] harmlessExceptions = {","path":"core/src/main/java/com/google/errorprone/bugpatterns/EmptyCatch.java","position":92,"original_position":92,"commit_id":"7e504174b664669ce480fab31e7052398aada68b","original_commit_id":"7e504174b664669ce480fab31e7052398aada68b","user":{"login":"eaftan","id":4733401,"avatar_url":"https://avatars.githubusercontent.com/u/4733401?v=3","gravatar_id":"","url":"https://api.github.com/users/eaftan","html_url":"https://github.com/eaftan","followers_url":"https://api.github.com/users/eaftan/followers","following_url":"https://api.github.com/users/eaftan/following{/other_user}","gists_url":"https://api.github.com/users/eaftan/gists{/gist_id}","starred_url":"https://api.github.com/users/eaftan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eaftan/subscriptions","organizations_url":"https://api.github.com/users/eaftan/orgs","repos_url":"https://api.github.com/users/eaftan/repos","events_url":"https://api.github.com/users/eaftan/events{/privacy}","received_events_url":"https://api.github.com/users/eaftan/received_events","type":"User","site_admin":false},"body":"Two things:\r\n1. I would use the fully qualified types here, e.g. \"java.io.FileNotFoundException\".\r\n2. Please use a set rather than a String array: `ImmutableSet<String> harmlessExceptions = ImmutableSet.of(\"java.io.FileNotFoundException\", \"java.lang.ReflectiveOperationException\", ...);`\r\nThen you can do the membership check by just doing `harmlessExceptions.contains(typeString);`","created_at":"2015-11-16T23:48:53Z","updated_at":"2015-11-16T23:48:53Z","html_url":"https://github.com/google/error-prone/pull/372#discussion_r45003323","pull_request_url":"https://api.github.com/repos/google/error-prone/pulls/372","_links":{"self":{"href":"https://api.github.com/repos/google/error-prone/pulls/comments/45003323"},"html":{"href":"https://github.com/google/error-prone/pull/372#discussion_r45003323"},"pull_request":{"href":"https://api.github.com/repos/google/error-prone/pulls/372"}}},"pull_request":{"url":"https://api.github.com/repos/google/error-prone/pulls/372","id":49736003,"html_url":"https://github.com/google/error-prone/pull/372","diff_url":"https://github.com/google/error-prone/pull/372.diff","patch_url":"https://github.com/google/error-prone/pull/372.patch","issue_url":"https://api.github.com/repos/google/error-prone/issues/372","number":372,"state":"open","locked":false,"title":"Checks on exception handling code","user":{"login":"diy1","id":5174169,"avatar_url":"https://avatars.githubusercontent.com/u/5174169?v=3","gravatar_id":"","url":"https://api.github.com/users/diy1","html_url":"https://github.com/diy1","followers_url":"https://api.github.com/users/diy1/followers","following_url":"https://api.github.com/users/diy1/following{/other_user}","gists_url":"https://api.github.com/users/diy1/gists{/gist_id}","starred_url":"https://api.github.com/users/diy1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/diy1/subscriptions","organizations_url":"https://api.github.com/users/diy1/orgs","repos_url":"https://api.github.com/users/diy1/repos","events_url":"https://api.github.com/users/diy1/events{/privacy}","received_events_url":"https://api.github.com/users/diy1/received_events","type":"User","site_admin":false},"body":"In our recent research paper with the title [\"Simple Testing Can Prevent Most Critical Failures\"] (https://www.usenix.org/system/files/conference/osdi14/osdi14-paper-yuan.pdf), we found that a large number of the most deadly failures in production distributed systems are the result of trivial mistakes in exception handling code. Exception handling code is particularly critical to distributed systems as they're often the last line of defence. We observed three simple, yet deadly, bug patterns:\r\n - \"TODO\"/\"FIXME\" in the catch block\r\n - Empty catch block\r\n - Abort in exception over-catch\r\n\r\nWe implemented a simple checker called Aspirator to detect these three types of mistakes, and it found and fixed hundreds of bugs from Hadoop, HBase, Spark, etc. [HBase developers asked us to implement these checks into error-prone] (https://issues.apache.org/jira/browse/HBASE-12187), therefore I'm providing these three checks in this pull request.","created_at":"2015-11-04T19:49:07Z","updated_at":"2015-11-16T23:48:53Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0a5776db9a8c97979489de61ed7f1b1d7f9957df","assignee":{"login":"eaftan","id":4733401,"avatar_url":"https://avatars.githubusercontent.com/u/4733401?v=3","gravatar_id":"","url":"https://api.github.com/users/eaftan","html_url":"https://github.com/eaftan","followers_url":"https://api.github.com/users/eaftan/followers","following_url":"https://api.github.com/users/eaftan/following{/other_user}","gists_url":"https://api.github.com/users/eaftan/gists{/gist_id}","starred_url":"https://api.github.com/users/eaftan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eaftan/subscriptions","organizations_url":"https://api.github.com/users/eaftan/orgs","repos_url":"https://api.github.com/users/eaftan/repos","events_url":"https://api.github.com/users/eaftan/events{/privacy}","received_events_url":"https://api.github.com/users/eaftan/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/google/error-prone/pulls/372/commits","review_comments_url":"https://api.github.com/repos/google/error-prone/pulls/372/comments","review_comment_url":"https://api.github.com/repos/google/error-prone/pulls/comments{/number}","comments_url":"https://api.github.com/repos/google/error-prone/issues/372/comments","statuses_url":"https://api.github.com/repos/google/error-prone/statuses/7e504174b664669ce480fab31e7052398aada68b","head":{"label":"diy1:master","ref":"master","sha":"7e504174b664669ce480fab31e7052398aada68b","user":{"login":"diy1","id":5174169,"avatar_url":"https://avatars.githubusercontent.com/u/5174169?v=3","gravatar_id":"","url":"https://api.github.com/users/diy1","html_url":"https://github.com/diy1","followers_url":"https://api.github.com/users/diy1/followers","following_url":"https://api.github.com/users/diy1/following{/other_user}","gists_url":"https://api.github.com/users/diy1/gists{/gist_id}","starred_url":"https://api.github.com/users/diy1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/diy1/subscriptions","organizations_url":"https://api.github.com/users/diy1/orgs","repos_url":"https://api.github.com/users/diy1/repos","events_url":"https://api.github.com/users/diy1/events{/privacy}","received_events_url":"https://api.github.com/users/diy1/received_events","type":"User","site_admin":false},"repo":{"id":42322929,"name":"error-prone","full_name":"diy1/error-prone","owner":{"login":"diy1","id":5174169,"avatar_url":"https://avatars.githubusercontent.com/u/5174169?v=3","gravatar_id":"","url":"https://api.github.com/users/diy1","html_url":"https://github.com/diy1","followers_url":"https://api.github.com/users/diy1/followers","following_url":"https://api.github.com/users/diy1/following{/other_user}","gists_url":"https://api.github.com/users/diy1/gists{/gist_id}","starred_url":"https://api.github.com/users/diy1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/diy1/subscriptions","organizations_url":"https://api.github.com/users/diy1/orgs","repos_url":"https://api.github.com/users/diy1/repos","events_url":"https://api.github.com/users/diy1/events{/privacy}","received_events_url":"https://api.github.com/users/diy1/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/diy1/error-prone","description":"Catch common Java mistakes as compile-time errors","fork":true,"url":"https://api.github.com/repos/diy1/error-prone","forks_url":"https://api.github.com/repos/diy1/error-prone/forks","keys_url":"https://api.github.com/repos/diy1/error-prone/keys{/key_id}","collaborators_url":"https://api.github.com/repos/diy1/error-prone/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/diy1/error-prone/teams","hooks_url":"https://api.github.com/repos/diy1/error-prone/hooks","issue_events_url":"https://api.github.com/repos/diy1/error-prone/issues/events{/number}","events_url":"https://api.github.com/repos/diy1/error-prone/events","assignees_url":"https://api.github.com/repos/diy1/error-prone/assignees{/user}","branches_url":"https://api.github.com/repos/diy1/error-prone/branches{/branch}","tags_url":"https://api.github.com/repos/diy1/error-prone/tags","blobs_url":"https://api.github.com/repos/diy1/error-prone/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/diy1/error-prone/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/diy1/error-prone/git/refs{/sha}","trees_url":"https://api.github.com/repos/diy1/error-prone/git/trees{/sha}","statuses_url":"https://api.github.com/repos/diy1/error-prone/statuses/{sha}","languages_url":"https://api.github.com/repos/diy1/error-prone/languages","stargazers_url":"https://api.github.com/repos/diy1/error-prone/stargazers","contributors_url":"https://api.github.com/repos/diy1/error-prone/contributors","subscribers_url":"https://api.github.com/repos/diy1/error-prone/subscribers","subscription_url":"https://api.github.com/repos/diy1/error-prone/subscription","commits_url":"https://api.github.com/repos/diy1/error-prone/commits{/sha}","git_commits_url":"https://api.github.com/repos/diy1/error-prone/git/commits{/sha}","comments_url":"https://api.github.com/repos/diy1/error-prone/comments{/number}","issue_comment_url":"https://api.github.com/repos/diy1/error-prone/issues/comments{/number}","contents_url":"https://api.github.com/repos/diy1/error-prone/contents/{+path}","compare_url":"https://api.github.com/repos/diy1/error-prone/compare/{base}...{head}","merges_url":"https://api.github.com/repos/diy1/error-prone/merges","archive_url":"https://api.github.com/repos/diy1/error-prone/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/diy1/error-prone/downloads","issues_url":"https://api.github.com/repos/diy1/error-prone/issues{/number}","pulls_url":"https://api.github.com/repos/diy1/error-prone/pulls{/number}","milestones_url":"https://api.github.com/repos/diy1/error-prone/milestones{/number}","notifications_url":"https://api.github.com/repos/diy1/error-prone/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/diy1/error-prone/labels{/name}","releases_url":"https://api.github.com/repos/diy1/error-prone/releases{/id}","created_at":"2015-09-11T17:35:19Z","updated_at":"2015-09-11T17:35:20Z","pushed_at":"2015-11-04T19:18:36Z","git_url":"git://github.com/diy1/error-prone.git","ssh_url":"git@github.com:diy1/error-prone.git","clone_url":"https://github.com/diy1/error-prone.git","svn_url":"https://github.com/diy1/error-prone","homepage":"","size":23579,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"google:master","ref":"master","sha":"8beb689411bf02328f78529e4e5847b16127ebb5","user":{"login":"google","id":1342004,"avatar_url":"https://avatars.githubusercontent.com/u/1342004?v=3","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"repo":{"id":23206290,"name":"error-prone","full_name":"google/error-prone","owner":{"login":"google","id":1342004,"avatar_url":"https://avatars.githubusercontent.com/u/1342004?v=3","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/google/error-prone","description":"Catch common Java mistakes as compile-time errors","fork":false,"url":"https://api.github.com/repos/google/error-prone","forks_url":"https://api.github.com/repos/google/error-prone/forks","keys_url":"https://api.github.com/repos/google/error-prone/keys{/key_id}","collaborators_url":"https://api.github.com/repos/google/error-prone/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/google/error-prone/teams","hooks_url":"https://api.github.com/repos/google/error-prone/hooks","issue_events_url":"https://api.github.com/repos/google/error-prone/issues/events{/number}","events_url":"https://api.github.com/repos/google/error-prone/events","assignees_url":"https://api.github.com/repos/google/error-prone/assignees{/user}","branches_url":"https://api.github.com/repos/google/error-prone/branches{/branch}","tags_url":"https://api.github.com/repos/google/error-prone/tags","blobs_url":"https://api.github.com/repos/google/error-prone/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/google/error-prone/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/google/error-prone/git/refs{/sha}","trees_url":"https://api.github.com/repos/google/error-prone/git/trees{/sha}","statuses_url":"https://api.github.com/repos/google/error-prone/statuses/{sha}","languages_url":"https://api.github.com/repos/google/error-prone/languages","stargazers_url":"https://api.github.com/repos/google/error-prone/stargazers","contributors_url":"https://api.github.com/repos/google/error-prone/contributors","subscribers_url":"https://api.github.com/repos/google/error-prone/subscribers","subscription_url":"https://api.github.com/repos/google/error-prone/subscription","commits_url":"https://api.github.com/repos/google/error-prone/commits{/sha}","git_commits_url":"https://api.github.com/repos/google/error-prone/git/commits{/sha}","comments_url":"https://api.github.com/repos/google/error-prone/comments{/number}","issue_comment_url":"https://api.github.com/repos/google/error-prone/issues/comments{/number}","contents_url":"https://api.github.com/repos/google/error-prone/contents/{+path}","compare_url":"https://api.github.com/repos/google/error-prone/compare/{base}...{head}","merges_url":"https://api.github.com/repos/google/error-prone/merges","archive_url":"https://api.github.com/repos/google/error-prone/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/google/error-prone/downloads","issues_url":"https://api.github.com/repos/google/error-prone/issues{/number}","pulls_url":"https://api.github.com/repos/google/error-prone/pulls{/number}","milestones_url":"https://api.github.com/repos/google/error-prone/milestones{/number}","notifications_url":"https://api.github.com/repos/google/error-prone/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/google/error-prone/labels{/name}","releases_url":"https://api.github.com/repos/google/error-prone/releases{/id}","created_at":"2014-08-21T23:26:50Z","updated_at":"2015-11-15T17:54:28Z","pushed_at":"2015-11-07T00:27:05Z","git_url":"git://github.com/google/error-prone.git","ssh_url":"git@github.com:google/error-prone.git","clone_url":"https://github.com/google/error-prone.git","svn_url":"https://github.com/google/error-prone","homepage":"","size":45249,"stargazers_count":737,"watchers_count":737,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":57,"mirror_url":null,"open_issues_count":109,"forks":57,"open_issues":109,"watchers":737,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/google/error-prone/pulls/372"},"html":{"href":"https://github.com/google/error-prone/pull/372"},"issue":{"href":"https://api.github.com/repos/google/error-prone/issues/372"},"comments":{"href":"https://api.github.com/repos/google/error-prone/issues/372/comments"},"review_comments":{"href":"https://api.github.com/repos/google/error-prone/pulls/372/comments"},"review_comment":{"href":"https://api.github.com/repos/google/error-prone/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/google/error-prone/pulls/372/commits"},"statuses":{"href":"https://api.github.com/repos/google/error-prone/statuses/7e504174b664669ce480fab31e7052398aada68b"}}}}