{"action":"created","issue":{"url":"https://api.github.com/repos/spinnaker/kayenta/issues/419","repository_url":"https://api.github.com/repos/spinnaker/kayenta","labels_url":"https://api.github.com/repos/spinnaker/kayenta/issues/419/labels{/name}","comments_url":"https://api.github.com/repos/spinnaker/kayenta/issues/419/comments","events_url":"https://api.github.com/repos/spinnaker/kayenta/issues/419/events","html_url":"https://github.com/spinnaker/kayenta/issues/419","id":378392125,"node_id":"MDU6SXNzdWUzNzgzOTIxMjU=","number":419,"title":"Implement better API error responses","user":{"login":"fieldju","id":711726,"node_id":"MDQ6VXNlcjcxMTcyNg==","avatar_url":"https://avatars2.githubusercontent.com/u/711726?v=4","gravatar_id":"","url":"https://api.github.com/users/fieldju","html_url":"https://github.com/fieldju","followers_url":"https://api.github.com/users/fieldju/followers","following_url":"https://api.github.com/users/fieldju/following{/other_user}","gists_url":"https://api.github.com/users/fieldju/gists{/gist_id}","starred_url":"https://api.github.com/users/fieldju/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fieldju/subscriptions","organizations_url":"https://api.github.com/users/fieldju/orgs","repos_url":"https://api.github.com/users/fieldju/repos","events_url":"https://api.github.com/users/fieldju/events{/privacy}","received_events_url":"https://api.github.com/users/fieldju/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":{"login":"fieldju","id":711726,"node_id":"MDQ6VXNlcjcxMTcyNg==","avatar_url":"https://avatars2.githubusercontent.com/u/711726?v=4","gravatar_id":"","url":"https://api.github.com/users/fieldju","html_url":"https://github.com/fieldju","followers_url":"https://api.github.com/users/fieldju/followers","following_url":"https://api.github.com/users/fieldju/following{/other_user}","gists_url":"https://api.github.com/users/fieldju/gists{/gist_id}","starred_url":"https://api.github.com/users/fieldju/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fieldju/subscriptions","organizations_url":"https://api.github.com/users/fieldju/orgs","repos_url":"https://api.github.com/users/fieldju/repos","events_url":"https://api.github.com/users/fieldju/events{/privacy}","received_events_url":"https://api.github.com/users/fieldju/received_events","type":"User","site_admin":false},"assignees":[{"login":"fieldju","id":711726,"node_id":"MDQ6VXNlcjcxMTcyNg==","avatar_url":"https://avatars2.githubusercontent.com/u/711726?v=4","gravatar_id":"","url":"https://api.github.com/users/fieldju","html_url":"https://github.com/fieldju","followers_url":"https://api.github.com/users/fieldju/followers","following_url":"https://api.github.com/users/fieldju/following{/other_user}","gists_url":"https://api.github.com/users/fieldju/gists{/gist_id}","starred_url":"https://api.github.com/users/fieldju/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fieldju/subscriptions","organizations_url":"https://api.github.com/users/fieldju/orgs","repos_url":"https://api.github.com/users/fieldju/repos","events_url":"https://api.github.com/users/fieldju/events{/privacy}","received_events_url":"https://api.github.com/users/fieldju/received_events","type":"User","site_admin":false}],"milestone":null,"comments":14,"created_at":"2018-11-07T17:29:02Z","updated_at":"2018-11-22T01:12:44Z","closed_at":null,"author_association":"COLLABORATOR","body":"While running Kayenta as a standalone microservice, I noticed that the error response are returned as such\r\n\r\n`Unable to resolve account im-memory.` with mime-type `text/plain;charset=UTF-8`\r\n\r\nThis makes it difficult to handle errors when using this service see the following example.\r\n```java\r\n    CanaryExecutionResponse canaryExecutionResponse;\r\n    try {\r\n      canaryExecutionResponse = kayentaService\r\n          .initiateCanaryWithConfig(stage.getExecution().getApplication(),\r\n              stage.getExecution().getId(), metricsAccount, storageAccount, request);\r\n    } catch (RetrofitError e) {\r\n      String msg;\r\n      try {\r\n        msg = IOUtils.toString(e.getResponse().getBody().in(), \"utf-8\");\r\n      } catch (Exception e1) {\r\n        msg = e.getMessage();\r\n      }\r\n      throw new RuntimeException(\"Failed to initiate canary analysis run with Kayenta: \" + msg);\r\n    }\r\n\r\n    String canaryPipelineExecutionId = canaryExecutionResponse.getCanaryExecutionId();\r\n```\r\n\r\nIt would be really nice to use a framework such as [Backstopper (framework-agnostic API error handling)](https://github.com/Nike-Inc/backstopper)\r\n\r\nWith Backstopper all errors would be mime-type `application/json;charset=UTF-8` and follow the same model.\r\n\r\nex:\r\n```json\r\n{\r\n  \"error_id\": \"408d516f-68d1-41f3-adb1-b3dc0affaaf2\",\r\n  \"errors\": [\r\n    {\r\n      \"code\": 43,\r\n      \"message\": \"Unable to resolve account im-memory.\"\r\n    }\r\n  ]\r\n}\r\n```\r\n\r\n[EDIT] This also gives a uuid that can be used to find the additional details in the logs.\r\nWith this using Kayenta from other microservices would be nicer. \r\n\r\nex:\r\n```java\r\n    CanaryExecutionResponse canaryExecutionResponse;\r\n    try {\r\n      canaryExecutionResponse = kayentaService\r\n          .initiateCanaryWithConfig(stage.getExecution().getApplication(),\r\n              stage.getExecution().getId(), metricsAccount, storageAccount, request);\r\n    } catch (RetrofitError e) {\r\n      ApiError error = (ApiError) e.getBodyAs(ApiError.class);\r\n      throw new RuntimeException(\"Failed to initiate canary analysis run with Kayenta: \" + \r\n          String.join(\", \", error.getErrors().stream()\r\n              .map(error -> error.getMessage())\r\n              .collect(Collectors.toList())));\r\n    }\r\n```\r\n\r\nThis would change the mime-type of the error responses, so maybe thats too much of a change?\r\n\r\nIf this is something that sounds like a good idea please let me know and I can make a PR or else feel free to close this issue."},"comment":{"url":"https://api.github.com/repos/spinnaker/kayenta/issues/comments/440877083","html_url":"https://github.com/spinnaker/kayenta/issues/419#issuecomment-440877083","issue_url":"https://api.github.com/repos/spinnaker/kayenta/issues/419","id":440877083,"node_id":"MDEyOklzc3VlQ29tbWVudDQ0MDg3NzA4Mw==","user":{"login":"Aloren","id":1207414,"node_id":"MDQ6VXNlcjEyMDc0MTQ=","avatar_url":"https://avatars1.githubusercontent.com/u/1207414?v=4","gravatar_id":"","url":"https://api.github.com/users/Aloren","html_url":"https://github.com/Aloren","followers_url":"https://api.github.com/users/Aloren/followers","following_url":"https://api.github.com/users/Aloren/following{/other_user}","gists_url":"https://api.github.com/users/Aloren/gists{/gist_id}","starred_url":"https://api.github.com/users/Aloren/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Aloren/subscriptions","organizations_url":"https://api.github.com/users/Aloren/orgs","repos_url":"https://api.github.com/users/Aloren/repos","events_url":"https://api.github.com/users/Aloren/events{/privacy}","received_events_url":"https://api.github.com/users/Aloren/received_events","type":"User","site_admin":false},"created_at":"2018-11-22T01:12:44Z","updated_at":"2018-11-22T01:12:44Z","author_association":"NONE","body":"sorry, didn't get your last comment"}}
{"actor":{"display_login":"Aloren"}}