{"action":"created","comment":{"url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/pulls/comments/99966869","pull_request_review_id":20658258,"id":99966869,"diff_hunk":"@@ -0,0 +1,105 @@\n+package org.sagebionetworks.bridge.exceptions;\n+\n+import static org.junit.Assert.assertEquals;\n+import static org.mockito.Mockito.doThrow;\n+\n+import org.aopalliance.intercept.MethodInvocation;\n+import org.junit.Test;\n+import org.junit.runner.RunWith;\n+import org.mockito.Mock;\n+import org.mockito.runners.MockitoJUnitRunner;\n+\n+import org.sagebionetworks.bridge.TestUtils;\n+import org.sagebionetworks.bridge.json.BridgeObjectMapper;\n+import org.sagebionetworks.bridge.play.interceptors.ExceptionInterceptor;\n+\n+import com.fasterxml.jackson.databind.JsonNode;\n+\n+import play.mvc.Result;\n+import play.test.Helpers;\n+\n+@RunWith(MockitoJUnitRunner.class)\n+public class ConstraintViolationExceptionTest {\n+\n+    @Mock\n+    MethodInvocation invocation;\n+    \n+    @Test\n+    public void testConstruction() {\n+        ConstraintViolationException e = createException();\n+        \n+        assertEquals(\"Referenced in survey\", e.getMessage());\n+        assertEquals(\"surveyGuidValue\", e.getReferrerKeys().get(\"surveyGuid\"));\n+        assertEquals(\"createdOnValue\", e.getReferrerKeys().get(\"createdOn\"));\n+        assertEquals(\"schemaIdValue\", e.getEntityKeys().get(\"schemaId\"));\n+        assertEquals(\"10\", e.getEntityKeys().get(\"schemaRevision\"));\n+    }\n+    \n+    @Test\n+    public void serializesCorrectlyThroughInterceptor() throws Throwable {\n+        ConstraintViolationException e = createException();\n+        \n+        ExceptionInterceptor interceptor = new ExceptionInterceptor();\n+        \n+        TestUtils.mockPlayContext();\n+        doThrow(e).when(invocation).proceed();\n+        \n+        Result result = (Result)interceptor.invoke(invocation);\n+        \n+        assertEquals(409, result.status());\n+        JsonNode node = BridgeObjectMapper.get().readTree(Helpers.contentAsString(result));\n+        \n+        assertEquals(\"Referenced in survey\", node.get(\"message\").asText());\n+        assertEquals(\"ConstraintViolationException\", node.get(\"type\").asText());\n+        assertEquals(409, node.get(\"statusCode\").asInt());\n+        \n+        JsonNode entityKeys = node.get(\"entityKeys\");\n+        assertEquals(\"schemaIdValue\", entityKeys.get(\"schemaId\").asText());\n+        assertEquals(\"10\", entityKeys.get(\"schemaRevision\").asText());","path":"test/org/sagebionetworks/bridge/exceptions/ConstraintViolationExceptionTest.java","position":58,"original_position":58,"commit_id":"7728f93bb5b07f26ae1f3467eb87d634033d4d9f","original_commit_id":"7728f93bb5b07f26ae1f3467eb87d634033d4d9f","user":{"login":"alxdarksage","id":5589085,"avatar_url":"https://avatars.githubusercontent.com/u/5589085?v=3","gravatar_id":"","url":"https://api.github.com/users/alxdarksage","html_url":"https://github.com/alxdarksage","followers_url":"https://api.github.com/users/alxdarksage/followers","following_url":"https://api.github.com/users/alxdarksage/following{/other_user}","gists_url":"https://api.github.com/users/alxdarksage/gists{/gist_id}","starred_url":"https://api.github.com/users/alxdarksage/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alxdarksage/subscriptions","organizations_url":"https://api.github.com/users/alxdarksage/orgs","repos_url":"https://api.github.com/users/alxdarksage/repos","events_url":"https://api.github.com/users/alxdarksage/events{/privacy}","received_events_url":"https://api.github.com/users/alxdarksage/received_events","type":"User","site_admin":false},"body":"This should probably be a Map<String,Object> so it can store revision as a number","created_at":"2017-02-08T00:34:04Z","updated_at":"2017-02-08T00:34:04Z","html_url":"https://github.com/Sage-Bionetworks/BridgePF/pull/1366#discussion_r99966869","pull_request_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/pulls/1366","_links":{"self":{"href":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/pulls/comments/99966869"},"html":{"href":"https://github.com/Sage-Bionetworks/BridgePF/pull/1366#discussion_r99966869"},"pull_request":{"href":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/pulls/1366"}}},"pull_request":{"url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/pulls/1366","id":105122311,"html_url":"https://github.com/Sage-Bionetworks/BridgePF/pull/1366","diff_url":"https://github.com/Sage-Bionetworks/BridgePF/pull/1366.diff","patch_url":"https://github.com/Sage-Bionetworks/BridgePF/pull/1366.patch","issue_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/issues/1366","number":1366,"state":"open","locked":false,"title":"Improvements to exception-based responses","user":{"login":"alxdarksage","id":5589085,"avatar_url":"https://avatars.githubusercontent.com/u/5589085?v=3","gravatar_id":"","url":"https://api.github.com/users/alxdarksage","html_url":"https://github.com/alxdarksage","followers_url":"https://api.github.com/users/alxdarksage/followers","following_url":"https://api.github.com/users/alxdarksage/following{/other_user}","gists_url":"https://api.github.com/users/alxdarksage/gists{/gist_id}","starred_url":"https://api.github.com/users/alxdarksage/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alxdarksage/subscriptions","organizations_url":"https://api.github.com/users/alxdarksage/orgs","repos_url":"https://api.github.com/users/alxdarksage/repos","events_url":"https://api.github.com/users/alxdarksage/events{/privacy}","received_events_url":"https://api.github.com/users/alxdarksage/received_events","type":"User","site_admin":false},"body":"In creating a ConstraintViolationException I wanted to have some extra information in the JSON generated by the exception. which caused me to recognize that our handling of exception serialization was pretty bad (I don't believe we were serializing anything unless we specified it in a handler class that was doing instanceof checks... not very maintainable).\r\n\r\n(Addresses BRIDGE-1697, BRIDGE-1372).\r\n\r\nChanged the following:\r\n- changed ExceptionInterceptor to serialize exceptions directly and then remove the fields that are specific to Throwables and not desirable to return to clients (this allows extra fields in our business exceptions to be exposed);\r\n- added a couple of fields to the standard exception JSON: statusCode and type\r\n- changed the BridgeErrorHandler which was returning everything as a 400 with an HTML response body, rather than the real response code at that point and a JSON payload that will work with client-side expectations about the content being returned;\r\n- the BridgeErrorHandler now returns a different payload for 404s generated by the fact that an URL on the server is wrong, vs. a 404 because an entity doesn't exist in Bridge (type EndpointNotFoundException vs. type EntityNotFoundException)\r\n- changed EntityAlreadyExistsException so it can handle any keys for any entity more generically;","created_at":"2017-02-08T00:06:28Z","updated_at":"2017-02-08T00:34:04Z","closed_at":null,"merged_at":null,"merge_commit_sha":"9edc6feb1b20c6c4bbf4a037726c0b1cdd31c21f","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/pulls/1366/commits","review_comments_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/pulls/1366/comments","review_comment_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/issues/1366/comments","statuses_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/statuses/7728f93bb5b07f26ae1f3467eb87d634033d4d9f","head":{"label":"alxdarksage:referential-integrity","ref":"referential-integrity","sha":"7728f93bb5b07f26ae1f3467eb87d634033d4d9f","user":{"login":"alxdarksage","id":5589085,"avatar_url":"https://avatars.githubusercontent.com/u/5589085?v=3","gravatar_id":"","url":"https://api.github.com/users/alxdarksage","html_url":"https://github.com/alxdarksage","followers_url":"https://api.github.com/users/alxdarksage/followers","following_url":"https://api.github.com/users/alxdarksage/following{/other_user}","gists_url":"https://api.github.com/users/alxdarksage/gists{/gist_id}","starred_url":"https://api.github.com/users/alxdarksage/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alxdarksage/subscriptions","organizations_url":"https://api.github.com/users/alxdarksage/orgs","repos_url":"https://api.github.com/users/alxdarksage/repos","events_url":"https://api.github.com/users/alxdarksage/events{/privacy}","received_events_url":"https://api.github.com/users/alxdarksage/received_events","type":"User","site_admin":false},"repo":{"id":45479946,"name":"BridgePF","full_name":"alxdarksage/BridgePF","owner":{"login":"alxdarksage","id":5589085,"avatar_url":"https://avatars.githubusercontent.com/u/5589085?v=3","gravatar_id":"","url":"https://api.github.com/users/alxdarksage","html_url":"https://github.com/alxdarksage","followers_url":"https://api.github.com/users/alxdarksage/followers","following_url":"https://api.github.com/users/alxdarksage/following{/other_user}","gists_url":"https://api.github.com/users/alxdarksage/gists{/gist_id}","starred_url":"https://api.github.com/users/alxdarksage/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alxdarksage/subscriptions","organizations_url":"https://api.github.com/users/alxdarksage/orgs","repos_url":"https://api.github.com/users/alxdarksage/repos","events_url":"https://api.github.com/users/alxdarksage/events{/privacy}","received_events_url":"https://api.github.com/users/alxdarksage/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/alxdarksage/BridgePF","description":"Server software for Bridge-based mobile applications","fork":true,"url":"https://api.github.com/repos/alxdarksage/BridgePF","forks_url":"https://api.github.com/repos/alxdarksage/BridgePF/forks","keys_url":"https://api.github.com/repos/alxdarksage/BridgePF/keys{/key_id}","collaborators_url":"https://api.github.com/repos/alxdarksage/BridgePF/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/alxdarksage/BridgePF/teams","hooks_url":"https://api.github.com/repos/alxdarksage/BridgePF/hooks","issue_events_url":"https://api.github.com/repos/alxdarksage/BridgePF/issues/events{/number}","events_url":"https://api.github.com/repos/alxdarksage/BridgePF/events","assignees_url":"https://api.github.com/repos/alxdarksage/BridgePF/assignees{/user}","branches_url":"https://api.github.com/repos/alxdarksage/BridgePF/branches{/branch}","tags_url":"https://api.github.com/repos/alxdarksage/BridgePF/tags","blobs_url":"https://api.github.com/repos/alxdarksage/BridgePF/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/alxdarksage/BridgePF/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/alxdarksage/BridgePF/git/refs{/sha}","trees_url":"https://api.github.com/repos/alxdarksage/BridgePF/git/trees{/sha}","statuses_url":"https://api.github.com/repos/alxdarksage/BridgePF/statuses/{sha}","languages_url":"https://api.github.com/repos/alxdarksage/BridgePF/languages","stargazers_url":"https://api.github.com/repos/alxdarksage/BridgePF/stargazers","contributors_url":"https://api.github.com/repos/alxdarksage/BridgePF/contributors","subscribers_url":"https://api.github.com/repos/alxdarksage/BridgePF/subscribers","subscription_url":"https://api.github.com/repos/alxdarksage/BridgePF/subscription","commits_url":"https://api.github.com/repos/alxdarksage/BridgePF/commits{/sha}","git_commits_url":"https://api.github.com/repos/alxdarksage/BridgePF/git/commits{/sha}","comments_url":"https://api.github.com/repos/alxdarksage/BridgePF/comments{/number}","issue_comment_url":"https://api.github.com/repos/alxdarksage/BridgePF/issues/comments{/number}","contents_url":"https://api.github.com/repos/alxdarksage/BridgePF/contents/{+path}","compare_url":"https://api.github.com/repos/alxdarksage/BridgePF/compare/{base}...{head}","merges_url":"https://api.github.com/repos/alxdarksage/BridgePF/merges","archive_url":"https://api.github.com/repos/alxdarksage/BridgePF/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/alxdarksage/BridgePF/downloads","issues_url":"https://api.github.com/repos/alxdarksage/BridgePF/issues{/number}","pulls_url":"https://api.github.com/repos/alxdarksage/BridgePF/pulls{/number}","milestones_url":"https://api.github.com/repos/alxdarksage/BridgePF/milestones{/number}","notifications_url":"https://api.github.com/repos/alxdarksage/BridgePF/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/alxdarksage/BridgePF/labels{/name}","releases_url":"https://api.github.com/repos/alxdarksage/BridgePF/releases{/id}","deployments_url":"https://api.github.com/repos/alxdarksage/BridgePF/deployments","created_at":"2015-11-03T16:35:11Z","updated_at":"2016-01-26T18:47:13Z","pushed_at":"2017-02-08T00:20:26Z","git_url":"git://github.com/alxdarksage/BridgePF.git","ssh_url":"git@github.com:alxdarksage/BridgePF.git","clone_url":"https://github.com/alxdarksage/BridgePF.git","svn_url":"https://github.com/alxdarksage/BridgePF","homepage":"","size":76211,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"develop"}},"base":{"label":"Sage-Bionetworks:develop","ref":"develop","sha":"fccc929cf86a54cf6f23fe9ffdd93dd70e8bf372","user":{"login":"Sage-Bionetworks","id":1250897,"avatar_url":"https://avatars.githubusercontent.com/u/1250897?v=3","gravatar_id":"","url":"https://api.github.com/users/Sage-Bionetworks","html_url":"https://github.com/Sage-Bionetworks","followers_url":"https://api.github.com/users/Sage-Bionetworks/followers","following_url":"https://api.github.com/users/Sage-Bionetworks/following{/other_user}","gists_url":"https://api.github.com/users/Sage-Bionetworks/gists{/gist_id}","starred_url":"https://api.github.com/users/Sage-Bionetworks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Sage-Bionetworks/subscriptions","organizations_url":"https://api.github.com/users/Sage-Bionetworks/orgs","repos_url":"https://api.github.com/users/Sage-Bionetworks/repos","events_url":"https://api.github.com/users/Sage-Bionetworks/events{/privacy}","received_events_url":"https://api.github.com/users/Sage-Bionetworks/received_events","type":"Organization","site_admin":false},"repo":{"id":18604783,"name":"BridgePF","full_name":"Sage-Bionetworks/BridgePF","owner":{"login":"Sage-Bionetworks","id":1250897,"avatar_url":"https://avatars.githubusercontent.com/u/1250897?v=3","gravatar_id":"","url":"https://api.github.com/users/Sage-Bionetworks","html_url":"https://github.com/Sage-Bionetworks","followers_url":"https://api.github.com/users/Sage-Bionetworks/followers","following_url":"https://api.github.com/users/Sage-Bionetworks/following{/other_user}","gists_url":"https://api.github.com/users/Sage-Bionetworks/gists{/gist_id}","starred_url":"https://api.github.com/users/Sage-Bionetworks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Sage-Bionetworks/subscriptions","organizations_url":"https://api.github.com/users/Sage-Bionetworks/orgs","repos_url":"https://api.github.com/users/Sage-Bionetworks/repos","events_url":"https://api.github.com/users/Sage-Bionetworks/events{/privacy}","received_events_url":"https://api.github.com/users/Sage-Bionetworks/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Sage-Bionetworks/BridgePF","description":"Server software for Bridge-based mobile applications","fork":false,"url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF","forks_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/forks","keys_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/teams","hooks_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/hooks","issue_events_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/issues/events{/number}","events_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/events","assignees_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/assignees{/user}","branches_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/branches{/branch}","tags_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/tags","blobs_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/git/refs{/sha}","trees_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/statuses/{sha}","languages_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/languages","stargazers_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/stargazers","contributors_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/contributors","subscribers_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/subscribers","subscription_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/subscription","commits_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/commits{/sha}","git_commits_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/git/commits{/sha}","comments_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/comments{/number}","issue_comment_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/issues/comments{/number}","contents_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/contents/{+path}","compare_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/merges","archive_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/downloads","issues_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/issues{/number}","pulls_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/pulls{/number}","milestones_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/milestones{/number}","notifications_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/labels{/name}","releases_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/releases{/id}","deployments_url":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/deployments","created_at":"2014-04-09T16:38:46Z","updated_at":"2016-11-01T16:00:22Z","pushed_at":"2017-02-08T00:20:28Z","git_url":"git://github.com/Sage-Bionetworks/BridgePF.git","ssh_url":"git@github.com:Sage-Bionetworks/BridgePF.git","clone_url":"https://github.com/Sage-Bionetworks/BridgePF.git","svn_url":"https://github.com/Sage-Bionetworks/BridgePF","homepage":"","size":76069,"stargazers_count":8,"watchers_count":8,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":20,"mirror_url":null,"open_issues_count":5,"forks":20,"open_issues":5,"watchers":8,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/pulls/1366"},"html":{"href":"https://github.com/Sage-Bionetworks/BridgePF/pull/1366"},"issue":{"href":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/issues/1366"},"comments":{"href":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/issues/1366/comments"},"review_comments":{"href":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/pulls/1366/comments"},"review_comment":{"href":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/pulls/1366/commits"},"statuses":{"href":"https://api.github.com/repos/Sage-Bionetworks/BridgePF/statuses/7728f93bb5b07f26ae1f3467eb87d634033d4d9f"}}}}
{"actor":{"display_login":"alxdarksage"}}