From 5a720a677edba469b8b816d3e070c566a001ff79 Mon Sep 17 00:00:00 2001 From: jbranchaud Date: Mon, 23 Mar 2020 15:41:46 -0500 Subject: [PATCH] Add Order Matters For Rescue From Blocks as a rails til --- README.md | 3 +- rails/order-matters-for-rescue-from-blocks.md | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 rails/order-matters-for-rescue-from-blocks.md diff --git a/README.md b/README.md index 210fc64..bef048a 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ and pairing with smart people at Hashrocket. For a steady stream of TILs, [sign up for my newsletter](https://tinyletter.com/jbranchaud). -_904 TILs and counting..._ +_905 TILs and counting..._ --- @@ -560,6 +560,7 @@ _904 TILs and counting..._ - [Mark For Destruction](rails/mark-for-destruction.md) - [Merge A Scope Into An ActiveRecord Query](rails/merge-a-scope-into-an-activerecord-query.md) - [Migrating Up Down Up](rails/migrating-up-down-up.md) +- [Order Matters For `rescue_from` Blocks](rails/order-matters-for-rescue-from-blocks.md) - [Params Includes Submission Button Info](rails/params-includes-submission-button-info.md) - [Perform SQL Explain With ActiveRecord](rails/perform-sql-explain-with-activerecord.md) - [Polymorphic Path Helpers](rails/polymorphic-path-helpers.md) diff --git a/rails/order-matters-for-rescue-from-blocks.md b/rails/order-matters-for-rescue-from-blocks.md new file mode 100644 index 0000000..08bca06 --- /dev/null +++ b/rails/order-matters-for-rescue-from-blocks.md @@ -0,0 +1,36 @@ +# Order Matters For `rescue_from` Blocks + +In a Rails controller, you can declare any number of [`rescue_from` +blocks](https://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html) +for capturing and responding to execeptions that are raised by your +application. + +```ruby +class BooksController < BaseController + + rescue_from ForbiddenAction do |e| + render json: { error: e.message }.to_json, status: 403 + end + + rescue_from StandardError do |e| + render json: { error: e.message }.to_json, status: 500 + end + + def index + # ... + + raise ForbiddenAction, "Which rescue_from is this going to hit?" + end +end +``` + +The potential problem with above is the ordering of the two `rescue_from` +blocks. Assume that `ForbiddenAction` is a subclass of the `StandardError` +class -- this is likely the case for exceptions you declare in your app. The +top `rescue_from` will never get hit because everything that subclasses +`StandardError` will be trapped by the bottom `rescue_from`. + +These `rescue_from` blocks are applied bottom-up. That means you have to +consider the class hierarchy when structuring your code. In the above code +example, if we flip the two of them around, we will then get what we are +expecting.