module Roda::RodaPlugins::InvalidRequestBody

  1. lib/roda/plugins/invalid_request_body.rb

The invalid_request_body plugin allows for custom handling of invalid request bodies. Roda uses Rack for parsing request bodies, so by default, any invalid request bodies would result in Rack raising an exception, and the exception could change for different reasons the request body is invalid. This plugin overrides RodaRequest#POST (which parses parameters from request bodies), and if parsing raises an exception, it allows for custom behavior.

If you want to treat an invalid request body as the submission of no parameters, you can use the :empty_hash argument when loading the plugin:

plugin :invalid_request_body, :empty_hash

If you want to return a empty 400 (Bad Request) response if an invalid request body is submitted, you can use the :empty_400 argument when loading the plugin:

plugin :invalid_request_body, :empty_400

If you want to raise a Roda::RodaPlugins::InvalidRequestBody::Error exception if an invalid request body is submitted (which makes it easier to handle these exceptions when using the error_handler plugin), you can use the :raise argument when loading the plugin:

plugin :invalid_request_body, :raise

For custom behavior, you can pass a block when loading the plugin. The block is called with the exception Rack raised when parsing the body. The block will be used to define a method in the application’s RodaRequest class. It can either return a hash of parameters, or you can raise a different exception, or you can halt processing and return a response:

plugin :invalid_request_body do |exception|
  # To treat the exception raised as a submitted parameter
  {body_error: exception}
end

You can use the rescue_classes argument when loading the plugin to only rescue specific exception classes:

plugin :invalid_request_body, :empty_hash, rescue_classes: Rack::BadRequest

However, this can be risky, because there have been many cases in the past where Rack can rescue classes such as ArgumentError or NoMethodError when parsing invalid request bodies. The default for rescue_classes is StandardError.

Methods

Public Class

  1. configure

Constants

Error = Class.new(RodaError)  

Exception class raised for invalid request bodies.

Public Class methods

configure(app, action=nil, rescue_classes: StandardError, &block)

Set the action to use (:empty_400, :empty_hash, :raise) for invalid request bodies, or use a block for custom behavior. The rescue_classes argument is an exception class or array of exception classes to rescue.

[show source]
   # File lib/roda/plugins/invalid_request_body.rb
56 def self.configure(app, action=nil, rescue_classes: StandardError, &block)
57   app.opts[:invalid_response_body_rescue_classes] = Array(rescue_classes).dup.freeze
58 
59   if action
60     if block
61       raise RodaError, "cannot provide both block and action when loading invalid_request_body plugin"
62     end
63 
64     method = :"handle_invalid_request_body_#{action}"
65     unless RequestMethods.private_method_defined?(method)
66       raise RodaError, "invalid invalid_request_body action provided: #{action}"
67     end
68 
69     app::RodaRequest.send(:alias_method, :handle_invalid_request_body, method)
70   elsif block
71     app::RodaRequest.class_exec do
72       define_method(:handle_invalid_request_body, &block)
73       alias handle_invalid_request_body handle_invalid_request_body
74     end
75   else
76     raise RodaError, "must provide block or action when loading invalid_request_body plugin"
77   end
78 
79   app::RodaRequest.send(:private, :handle_invalid_request_body)
80 end