Skip to content

Hash validation raises NoMethodError exception when parameter is not a hash #182

Closed
@nathanhoel

Description

@nathanhoel

The Problem

Validation raises a NoMethodError (undefined method `has_key?' for "not a hash":String) with the following code

Parameters

param :foo, Hash, :desc => "foo description" do
  param :bar, String, :desc => "bar description"
end

Note: the example in the documentation would also suffice to cause this error

Then send send request to your server with a body that looks like this:

{
  "foo" : "not a hash"
}

Note: sending an array instead of a string causes the same exception

What is expected is that Apipie would raise a validation exception about the parameter not being a hash.

Why it happens?

From what I can tell the hash validator's validate method tries to validate all it's children recursively first before validating itself (if it ever validates itself I cannot tell).

def validate(value)
  if @hash_params
    @hash_params.each do |k, p|
      if Apipie.configuration.validate_presence?
        raise ParamMissing.new(k) if p.required && !value.has_key?(k)
      end
      if Apipie.configuration.validate_value?
        p.validate(value[k]) if value.has_key?(k)
      end
    end
  end
  return true
end

This loops over the child param definitions from the example above and then checks to see if that child parameter's key exists in the hash (value.has_key?(k)). This is great when the value IS a hash, however when it is not a hash (which is what we are trying to validate) then these 2 lines raise the NoMethodError exception (which line depends on if the method was set to required or not).

raise ParamMissing.new(k) if p.required && !value.has_key?(k)
...
p.validate(value[k]) if value.has_key?(k)

Is it legit?

I plan on trying to fix this but it would be really helpful to know if this is a legit problem.
I am a little skeptical that I am doing it correctly.

I would also like to point out that issue #166 possibly stumbled across the same error however the fix suggested allows validation to finish but will not raise a validation exception at all when the parameter is not a hash (which it should) so we can return status code 422.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions