{"action":"created","comment":{"url":"https://api.github.com/repos/rails/rails/pulls/comments/298790939","pull_request_review_id":256027574,"id":298790939,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDI5ODc5MDkzOQ==","diff_hunk":"@@ -1,3 +1,34 @@\n+*   Trigger `ActiveSupport::ActionableError` from existing errors.\n+\n+    Triggers let's you re raise an actionable error from an existing one, if it","path":"activesupport/CHANGELOG.md","position":35,"original_position":3,"commit_id":"4db841ae54b213b34a49b1130dde144e2bc41d7b","original_commit_id":"4e17eb6e54e41263db8716b822c19334ce4be406","user":{"login":"gsamokovarov","id":604618,"node_id":"MDQ6VXNlcjYwNDYxOA==","avatar_url":"https://avatars0.githubusercontent.com/u/604618?v=4","gravatar_id":"","url":"https://api.github.com/users/gsamokovarov","html_url":"https://github.com/gsamokovarov","followers_url":"https://api.github.com/users/gsamokovarov/followers","following_url":"https://api.github.com/users/gsamokovarov/following{/other_user}","gists_url":"https://api.github.com/users/gsamokovarov/gists{/gist_id}","starred_url":"https://api.github.com/users/gsamokovarov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gsamokovarov/subscriptions","organizations_url":"https://api.github.com/users/gsamokovarov/orgs","repos_url":"https://api.github.com/users/gsamokovarov/repos","events_url":"https://api.github.com/users/gsamokovarov/events{/privacy}","received_events_url":"https://api.github.com/users/gsamokovarov/received_events","type":"User","site_admin":false},"body":"Thanks! Fixed it.","created_at":"2019-06-29T07:18:52Z","updated_at":"2019-06-29T07:18:52Z","html_url":"https://github.com/rails/rails/pull/36455#discussion_r298790939","pull_request_url":"https://api.github.com/repos/rails/rails/pulls/36455","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/rails/rails/pulls/comments/298790939"},"html":{"href":"https://github.com/rails/rails/pull/36455#discussion_r298790939"},"pull_request":{"href":"https://api.github.com/repos/rails/rails/pulls/36455"}},"in_reply_to_id":292154449},"pull_request":{"url":"https://api.github.com/repos/rails/rails/pulls/36455","id":286767426,"node_id":"MDExOlB1bGxSZXF1ZXN0Mjg2NzY3NDI2","html_url":"https://github.com/rails/rails/pull/36455","diff_url":"https://github.com/rails/rails/pull/36455.diff","patch_url":"https://github.com/rails/rails/pull/36455.patch","issue_url":"https://api.github.com/repos/rails/rails/issues/36455","number":36455,"state":"open","locked":false,"title":"Hook up the new frameworks with Actionable Error","user":{"login":"gsamokovarov","id":604618,"node_id":"MDQ6VXNlcjYwNDYxOA==","avatar_url":"https://avatars0.githubusercontent.com/u/604618?v=4","gravatar_id":"","url":"https://api.github.com/users/gsamokovarov","html_url":"https://github.com/gsamokovarov","followers_url":"https://api.github.com/users/gsamokovarov/followers","following_url":"https://api.github.com/users/gsamokovarov/following{/other_user}","gists_url":"https://api.github.com/users/gsamokovarov/gists{/gist_id}","starred_url":"https://api.github.com/users/gsamokovarov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gsamokovarov/subscriptions","organizations_url":"https://api.github.com/users/gsamokovarov/orgs","repos_url":"https://api.github.com/users/gsamokovarov/repos","events_url":"https://api.github.com/users/gsamokovarov/events{/privacy}","received_events_url":"https://api.github.com/users/gsamokovarov/received_events","type":"User","site_admin":false},"body":"The idea behind actionable errors tries to help with the development experience at a start of a project or while trying to setup or test a new framework. I have introduced actionable errors if you try to use new frameworks, but forgot set them up.\r\n\r\n<details>\r\n  <summary>Active Storage (GIF example)</summary>\r\n\r\n  ![rails_active_storage](https://user-images.githubusercontent.com/604618/59213990-d085fd80-8bbe-11e9-8a77-fefa3b96cd28.gif)\r\n</details>\r\n\r\n<details>\r\n  <summary>Action Mailbox (GIF example)</summary>\r\n\r\n  ![rails_action_mailbox_optimized](https://user-images.githubusercontent.com/604618/59214217-50ac6300-8bbf-11e9-9721-d16842978475.gif)\r\n</details>\r\n\r\n<details>\r\n  <summary>Action Text (GIF example)</summary>\r\n\r\n  ![rails_action_text](https://user-images.githubusercontent.com/604618/59214234-5d30bb80-8bbf-11e9-9901-c433962fc600.gif)\r\n</details>\r\n\r\nThe current flow works, but we may see problems running possibly interactive commands like `yarn:install` from the Action Text actionable error.\r\n\r\nNow that we have actionable errors for all internal frameworks, if we want plugin developers to use them, have to be easy to define. Setting up the internal components gave us a common use case that we try to optimize for in this PR.\r\n\r\nYou can hook up an actionable error on the exception that crashes the application when you try to use the framework, without first setting it up.\r\n\r\n```ruby\r\nclass ActiveStorage::InstallError < Error\r\n  include ActiveSupport::ActionableError\r\n\r\n  def initialize(message = nil)\r\n    super(message || <<~MESSAGE)\r\n      Action Mailbox does not appear to be installed. Do you want to install it now?\r\n    MESSAGE\r\n  end\r\n\r\n  trigger on: ActiveRecord::StatementInvalid, if: -> error do # 👈\r\n    error.message.match?(InboundEmail.table_name)\r\n  end\r\n\r\n  action \"Install now\" do\r\n    Rails::Command.invoke(\"active_storage:install\")\r\n    Rails::Command.invoke(\"db:migrate\")\r\n  end\r\nend\r\n```\r\n\r\n\r\nThe trigger says: look for unhandled `ActiveRecord::StatementInvalid` errors and reraise the current actionable error (without any arguments to the its constructor, e.g. expect a default error message). The actionable error is risen by the `ActionDispatch::ActionableExceptions` middleware, which is already in the default middleware stack.\r\n\r\nThis makes the actionable errors self-contained – the code for the action and how they are triggered is in one place!\r\n\r\nThere are still some gotchas, though. You may want to define the error only if the `Rails::Railtie` are defined, as you may invoke commands with `Rails::Command`. In all the internal gems, we try to define the errors only if the gems are used with Rails, and not outside of it, as all of them (`activestorage`, `actionmailbox`, `actiontext`) do not explicitly depend on `railties`.\r\n\r\nIt may make sense to define the actionable errors in the railties with if this becomes a problem.\r\n\r\n<details>\r\n  <summary>Example of Actionable Error definition in a Railtie</summary>\r\n\r\n```ruby\r\n# WARNING: THIS IS HYPOTHETICAL! 😅\r\ninitializer \"active_storage.actionable_errors\" do\r\n  ActiveSupport::ActionableError.define :InstallError, under: ActiveStorage do\r\n    message <<~END\r\n      Action Mailbox does not appear to be installed. Do you want to install it now?\r\n    END\r\n\r\n    trigger on: ActiveRecord::StatementInvalid, if: -> error do # 👈\r\n      error.message.match?(InboundEmail.table_name)\r\n    end\r\n\r\n    action \"Install now\" do\r\n      Rails::Command.invoke(\"active_storage:install\")\r\n      Rails::Command.invoke(\"db:migrate\")j\r\n    end\r\n  end\r\nend\r\n```\r\n\r\n</details>\r\n\r\n## Known Problems\r\n\r\n- Action Text install does not find the yarn.lock file.\r\n- The output capture can create issues. I've seen action runs with only partial information.","created_at":"2019-06-10T17:38:40Z","updated_at":"2019-06-29T07:18:52Z","closed_at":null,"merged_at":null,"merge_commit_sha":"bbb58675e7f4082454db581a191d8bce7bb6150e","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":1174770998,"node_id":"MDU6TGFiZWwxMTc0NzcwOTk4","url":"https://api.github.com/repos/rails/rails/labels/actionmailbox","name":"actionmailbox","color":"f4a6cb","default":false},{"id":107189,"node_id":"MDU6TGFiZWwxMDcxODk=","url":"https://api.github.com/repos/rails/rails/labels/actionpack","name":"actionpack","color":"FFF700","default":false},{"id":1180817762,"node_id":"MDU6TGFiZWwxMTgwODE3NzYy","url":"https://api.github.com/repos/rails/rails/labels/actiontext","name":"actiontext","color":"3bc667","default":false},{"id":664533972,"node_id":"MDU6TGFiZWw2NjQ1MzM5NzI=","url":"https://api.github.com/repos/rails/rails/labels/activestorage","name":"activestorage","color":"bfd4f2","default":false},{"id":107194,"node_id":"MDU6TGFiZWwxMDcxOTQ=","url":"https://api.github.com/repos/rails/rails/labels/activesupport","name":"activesupport","color":"FC9300","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/rails/rails/pulls/36455/commits","review_comments_url":"https://api.github.com/repos/rails/rails/pulls/36455/comments","review_comment_url":"https://api.github.com/repos/rails/rails/pulls/comments{/number}","comments_url":"https://api.github.com/repos/rails/rails/issues/36455/comments","statuses_url":"https://api.github.com/repos/rails/rails/statuses/4db841ae54b213b34a49b1130dde144e2bc41d7b","head":{"label":"gsamokovarov:actionable-errors-redux","ref":"actionable-errors-redux","sha":"4db841ae54b213b34a49b1130dde144e2bc41d7b","user":{"login":"gsamokovarov","id":604618,"node_id":"MDQ6VXNlcjYwNDYxOA==","avatar_url":"https://avatars0.githubusercontent.com/u/604618?v=4","gravatar_id":"","url":"https://api.github.com/users/gsamokovarov","html_url":"https://github.com/gsamokovarov","followers_url":"https://api.github.com/users/gsamokovarov/followers","following_url":"https://api.github.com/users/gsamokovarov/following{/other_user}","gists_url":"https://api.github.com/users/gsamokovarov/gists{/gist_id}","starred_url":"https://api.github.com/users/gsamokovarov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gsamokovarov/subscriptions","organizations_url":"https://api.github.com/users/gsamokovarov/orgs","repos_url":"https://api.github.com/users/gsamokovarov/repos","events_url":"https://api.github.com/users/gsamokovarov/events{/privacy}","received_events_url":"https://api.github.com/users/gsamokovarov/received_events","type":"User","site_admin":false},"repo":{"id":10368431,"node_id":"MDEwOlJlcG9zaXRvcnkxMDM2ODQzMQ==","name":"rails","full_name":"gsamokovarov/rails","private":false,"owner":{"login":"gsamokovarov","id":604618,"node_id":"MDQ6VXNlcjYwNDYxOA==","avatar_url":"https://avatars0.githubusercontent.com/u/604618?v=4","gravatar_id":"","url":"https://api.github.com/users/gsamokovarov","html_url":"https://github.com/gsamokovarov","followers_url":"https://api.github.com/users/gsamokovarov/followers","following_url":"https://api.github.com/users/gsamokovarov/following{/other_user}","gists_url":"https://api.github.com/users/gsamokovarov/gists{/gist_id}","starred_url":"https://api.github.com/users/gsamokovarov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gsamokovarov/subscriptions","organizations_url":"https://api.github.com/users/gsamokovarov/orgs","repos_url":"https://api.github.com/users/gsamokovarov/repos","events_url":"https://api.github.com/users/gsamokovarov/events{/privacy}","received_events_url":"https://api.github.com/users/gsamokovarov/received_events","type":"User","site_admin":false},"html_url":"https://github.com/gsamokovarov/rails","description":"Ruby on Rails","fork":true,"url":"https://api.github.com/repos/gsamokovarov/rails","forks_url":"https://api.github.com/repos/gsamokovarov/rails/forks","keys_url":"https://api.github.com/repos/gsamokovarov/rails/keys{/key_id}","collaborators_url":"https://api.github.com/repos/gsamokovarov/rails/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/gsamokovarov/rails/teams","hooks_url":"https://api.github.com/repos/gsamokovarov/rails/hooks","issue_events_url":"https://api.github.com/repos/gsamokovarov/rails/issues/events{/number}","events_url":"https://api.github.com/repos/gsamokovarov/rails/events","assignees_url":"https://api.github.com/repos/gsamokovarov/rails/assignees{/user}","branches_url":"https://api.github.com/repos/gsamokovarov/rails/branches{/branch}","tags_url":"https://api.github.com/repos/gsamokovarov/rails/tags","blobs_url":"https://api.github.com/repos/gsamokovarov/rails/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/gsamokovarov/rails/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/gsamokovarov/rails/git/refs{/sha}","trees_url":"https://api.github.com/repos/gsamokovarov/rails/git/trees{/sha}","statuses_url":"https://api.github.com/repos/gsamokovarov/rails/statuses/{sha}","languages_url":"https://api.github.com/repos/gsamokovarov/rails/languages","stargazers_url":"https://api.github.com/repos/gsamokovarov/rails/stargazers","contributors_url":"https://api.github.com/repos/gsamokovarov/rails/contributors","subscribers_url":"https://api.github.com/repos/gsamokovarov/rails/subscribers","subscription_url":"https://api.github.com/repos/gsamokovarov/rails/subscription","commits_url":"https://api.github.com/repos/gsamokovarov/rails/commits{/sha}","git_commits_url":"https://api.github.com/repos/gsamokovarov/rails/git/commits{/sha}","comments_url":"https://api.github.com/repos/gsamokovarov/rails/comments{/number}","issue_comment_url":"https://api.github.com/repos/gsamokovarov/rails/issues/comments{/number}","contents_url":"https://api.github.com/repos/gsamokovarov/rails/contents/{+path}","compare_url":"https://api.github.com/repos/gsamokovarov/rails/compare/{base}...{head}","merges_url":"https://api.github.com/repos/gsamokovarov/rails/merges","archive_url":"https://api.github.com/repos/gsamokovarov/rails/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/gsamokovarov/rails/downloads","issues_url":"https://api.github.com/repos/gsamokovarov/rails/issues{/number}","pulls_url":"https://api.github.com/repos/gsamokovarov/rails/pulls{/number}","milestones_url":"https://api.github.com/repos/gsamokovarov/rails/milestones{/number}","notifications_url":"https://api.github.com/repos/gsamokovarov/rails/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/gsamokovarov/rails/labels{/name}","releases_url":"https://api.github.com/repos/gsamokovarov/rails/releases{/id}","deployments_url":"https://api.github.com/repos/gsamokovarov/rails/deployments","created_at":"2013-05-29T20:12:58Z","updated_at":"2019-04-10T11:14:56Z","pushed_at":"2019-06-29T07:05:08Z","git_url":"git://github.com/gsamokovarov/rails.git","ssh_url":"git@github.com:gsamokovarov/rails.git","clone_url":"https://github.com/gsamokovarov/rails.git","svn_url":"https://github.com/gsamokovarov/rails","homepage":"http://rubyonrails.org","size":176628,"stargazers_count":1,"watchers_count":1,"language":"Ruby","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":0,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"forks":0,"open_issues":0,"watchers":1,"default_branch":"master"}},"base":{"label":"rails:master","ref":"master","sha":"c631e8d011a7cf3e7ade4e9e8db56d2b89bd530c","user":{"login":"rails","id":4223,"node_id":"MDEyOk9yZ2FuaXphdGlvbjQyMjM=","avatar_url":"https://avatars1.githubusercontent.com/u/4223?v=4","gravatar_id":"","url":"https://api.github.com/users/rails","html_url":"https://github.com/rails","followers_url":"https://api.github.com/users/rails/followers","following_url":"https://api.github.com/users/rails/following{/other_user}","gists_url":"https://api.github.com/users/rails/gists{/gist_id}","starred_url":"https://api.github.com/users/rails/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rails/subscriptions","organizations_url":"https://api.github.com/users/rails/orgs","repos_url":"https://api.github.com/users/rails/repos","events_url":"https://api.github.com/users/rails/events{/privacy}","received_events_url":"https://api.github.com/users/rails/received_events","type":"Organization","site_admin":false},"repo":{"id":8514,"node_id":"MDEwOlJlcG9zaXRvcnk4NTE0","name":"rails","full_name":"rails/rails","private":false,"owner":{"login":"rails","id":4223,"node_id":"MDEyOk9yZ2FuaXphdGlvbjQyMjM=","avatar_url":"https://avatars1.githubusercontent.com/u/4223?v=4","gravatar_id":"","url":"https://api.github.com/users/rails","html_url":"https://github.com/rails","followers_url":"https://api.github.com/users/rails/followers","following_url":"https://api.github.com/users/rails/following{/other_user}","gists_url":"https://api.github.com/users/rails/gists{/gist_id}","starred_url":"https://api.github.com/users/rails/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rails/subscriptions","organizations_url":"https://api.github.com/users/rails/orgs","repos_url":"https://api.github.com/users/rails/repos","events_url":"https://api.github.com/users/rails/events{/privacy}","received_events_url":"https://api.github.com/users/rails/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/rails/rails","description":"Ruby on Rails","fork":false,"url":"https://api.github.com/repos/rails/rails","forks_url":"https://api.github.com/repos/rails/rails/forks","keys_url":"https://api.github.com/repos/rails/rails/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rails/rails/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rails/rails/teams","hooks_url":"https://api.github.com/repos/rails/rails/hooks","issue_events_url":"https://api.github.com/repos/rails/rails/issues/events{/number}","events_url":"https://api.github.com/repos/rails/rails/events","assignees_url":"https://api.github.com/repos/rails/rails/assignees{/user}","branches_url":"https://api.github.com/repos/rails/rails/branches{/branch}","tags_url":"https://api.github.com/repos/rails/rails/tags","blobs_url":"https://api.github.com/repos/rails/rails/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rails/rails/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rails/rails/git/refs{/sha}","trees_url":"https://api.github.com/repos/rails/rails/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rails/rails/statuses/{sha}","languages_url":"https://api.github.com/repos/rails/rails/languages","stargazers_url":"https://api.github.com/repos/rails/rails/stargazers","contributors_url":"https://api.github.com/repos/rails/rails/contributors","subscribers_url":"https://api.github.com/repos/rails/rails/subscribers","subscription_url":"https://api.github.com/repos/rails/rails/subscription","commits_url":"https://api.github.com/repos/rails/rails/commits{/sha}","git_commits_url":"https://api.github.com/repos/rails/rails/git/commits{/sha}","comments_url":"https://api.github.com/repos/rails/rails/comments{/number}","issue_comment_url":"https://api.github.com/repos/rails/rails/issues/comments{/number}","contents_url":"https://api.github.com/repos/rails/rails/contents/{+path}","compare_url":"https://api.github.com/repos/rails/rails/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rails/rails/merges","archive_url":"https://api.github.com/repos/rails/rails/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rails/rails/downloads","issues_url":"https://api.github.com/repos/rails/rails/issues{/number}","pulls_url":"https://api.github.com/repos/rails/rails/pulls{/number}","milestones_url":"https://api.github.com/repos/rails/rails/milestones{/number}","notifications_url":"https://api.github.com/repos/rails/rails/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rails/rails/labels{/name}","releases_url":"https://api.github.com/repos/rails/rails/releases{/id}","deployments_url":"https://api.github.com/repos/rails/rails/deployments","created_at":"2008-04-11T02:19:47Z","updated_at":"2019-06-29T06:06:12Z","pushed_at":"2019-06-29T07:05:18Z","git_url":"git://github.com/rails/rails.git","ssh_url":"git@github.com:rails/rails.git","clone_url":"https://github.com/rails/rails.git","svn_url":"https://github.com/rails/rails","homepage":"https://rubyonrails.org","size":189031,"stargazers_count":43483,"watchers_count":43483,"language":"Ruby","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":17486,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":1166,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"forks":17486,"open_issues":1166,"watchers":43483,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/rails/rails/pulls/36455"},"html":{"href":"https://github.com/rails/rails/pull/36455"},"issue":{"href":"https://api.github.com/repos/rails/rails/issues/36455"},"comments":{"href":"https://api.github.com/repos/rails/rails/issues/36455/comments"},"review_comments":{"href":"https://api.github.com/repos/rails/rails/pulls/36455/comments"},"review_comment":{"href":"https://api.github.com/repos/rails/rails/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/rails/rails/pulls/36455/commits"},"statuses":{"href":"https://api.github.com/repos/rails/rails/statuses/4db841ae54b213b34a49b1130dde144e2bc41d7b"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"gsamokovarov"}}