Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom types can set a message to be used in the response when invalid #2157

Merged
merged 1 commit into from
Jan 30, 2021

Conversation

dnesteryuk
Copy link
Member

Just return an instance of Grape::Types::InvalidValue with the message:

class Color
  def self.parse(value)
    return value if %w[blue red green].include?(value)

    Grape::Types::InvalidValue.new('Invalid color')
  end
end

Any raised exception will be treated as an invalid value as it was before.

Implements an idea listed in #2093

@dnesteryuk dnesteryuk force-pushed the chore/custom-msg-in-invalid-value branch 3 times, most recently from 1e739a2 to 3d1760d Compare January 28, 2021 17:48
Just return an instance of `Grape::Types::InvalidValue` with the message:

    class Color
      def self.parse(value)
	return value if %w[blue red green].include?(value)

        Grape::Types::InvalidValue.new('Invalid color')
      end
    end

Any raised exception will be treated as an invalid value as it was before.
@dnesteryuk dnesteryuk force-pushed the chore/custom-msg-in-invalid-value branch from f8e509c to 54b2e11 Compare January 29, 2021 08:23
Copy link
Member

@dblock dblock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great, but I think we should rely on an exception to separate valid returns from errors in the flow. We could similarly rescue StandardError and convert it into something with more detail like a ParseError that would help the caller identify the actual parameter that could not be parsed. WDYT?

new(value)
return new(value) if %w[blue red green]).include?(value)

Grape::Types::InvalidValue.new('Unsupported color')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this should be a raise that gets handled, not a return.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How will we know that an exception message should be returned to the user if we rescue StandardError? I would like to avoid guessing 🙂 We already return the invalid value there and there and there.

In general, if there is an easy way to return a value indicating a failure, I prefer to do that. It is cheaper:

require 'benchmark/ips'

def return_value
  :invalid
end

def raise_exception
  raise StandardError
end

Benchmark.ips do |x|
  x.report('return value') do
    return_value
  end
  x.report('raise error') do
    begin
      raise_exception
    rescue StandardError
    end
  end

  x.compare!
end
Warming up --------------------------------------
        return value     1.990M i/100ms
         raise error   149.703k i/100ms
Calculating -------------------------------------
        return value     19.948M (± 0.4%) i/s -    101.470M in   5.086841s
         raise error      1.513M (± 0.5%) i/s -      7.635M in   5.044907s

Comparison:
        return value: 19947800.7 i/s
         raise error:  1513417.9 i/s - 13.18x  (± 0.00) slower

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I clearly didn't do my homework, especially on the existing code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants