Search code examples
ruby-on-railsruby-on-rails-5savon

Rails 5: How to declare HEAD 200 in Rescue


I have a webhook sent to a page on my app, and I am catching SOAP errors from processing the data, but I want to send to the webhook a 200 status. Is this possible in the controller?

controller

def example_method

  ...

rescue Savon::SOAPFault => error

  ...
  
  # Respond to the HTTP POST request by giving the 'all clear'
  head 200

  raise

end

Solution

  • First off don't place soap calls directly into your controller - instead create a client class or service object that handles it.

    Your controller should only really know that it calls some kind of service and that it may fail or succeed - if you are catching library specific errors in your controller you are on your way down the rabbit hole.

    So how do you rescue exceptions in your controller?

    You can rescue them inline:

    class SomethingController
    
      def do_something
    
        begin
          # Something.this_may_blow_up!
        rescue SomeError => error
          head :ok and return
        end
      end
    end
    

    The key here is and return which halts the controller flow and prevents double render errors.

    The other method is by using rescue_from.

    class ThingsController
    
      rescue_from ActiveRecord::RecordNotFound do
        render :not_found and return
      end
    
      def show
        @thing = Thing.find(params[:id])
      end
    end
    

    The above is an example of how you can create a custom 404 page per controller. What happens is that when the action on the controller is invoked it is wrapped in a begin..rescue block that looks for rescue_from handlers in the controller.