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

add custom error formatter #76

Merged
merged 15 commits into from Oct 20, 2017
Merged

add custom error formatter #76

merged 15 commits into from Oct 20, 2017

Conversation

xn
Copy link
Contributor

@xn xn commented Aug 30, 2017

Would y'all be interested in having an error formatter that would allow for a jsonapi response?

If so, I can add some tests and documentation to this.

@dblock
Copy link
Member

dblock commented Aug 31, 2017

I think the answer is yes, we want a custom formatter for error messages, please.

@xn
Copy link
Contributor Author

xn commented Aug 31, 2017

Kk, leaving later today to go camping. I'll finish this out Monday or so when I get back.

@xn
Copy link
Contributor Author

xn commented Oct 2, 2017

@dblock Rubocop is going to complain about the method signature of #call. I have no control over that. What should I do?

@xn
Copy link
Contributor Author

xn commented Oct 2, 2017

I don't know what you want to do about 0.8. Please advise.

@dblock
Copy link
Member

dblock commented Oct 2, 2017

For rubocop run rubocop -a ; rubocop --auto-gen-config.

CHANGELOG.md Outdated
@@ -2,7 +2,7 @@

### 1.5.2 (Next)

* Your contribution here.
Copy link
Member

Choose a reason for hiding this comment

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

Put this back.

@@ -18,6 +18,7 @@ Gem::Specification.new do |gem|

gem.add_dependency 'grape', '>= 0.8.0'
gem.add_dependency 'active_model_serializers', '>= 0.10.0'
gem.add_dependency 'multi_json', '~> 1.0'
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we want this. Grape has a way to format JSON regardless of the library used, you can call it with ::Grape::Json.dump.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

uninitialized constant Grape::Json

Copy link
Member

Choose a reason for hiding this comment

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

It's here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Then do you want to change the version of grape depended on?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Or should we implement the same thing?

Copy link
Member

@dblock dblock Oct 5, 2017

Choose a reason for hiding this comment

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

This gem depends on grape, so you should be able to use it, I am not sure what the problem is, but maybe you need to make sure to depend on Grape >= 1.0 where this was added.

Copy link
Member

Choose a reason for hiding this comment

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

So, this one should still be removed, it's unnecessary in all Grape versions since it's either coming via Grape or is not used..

extend Base

class << self
# rubocop:disable Metrics/CyclomaticComplexity
Copy link
Member

Choose a reason for hiding this comment

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

Get rid of of the rubocop stuff here and do rubocop -a ; rubocop --auto-gen-config.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Inspecting 31 files
...C...........................

Offenses:

lib/grape-active_model_serializers/error_formatter.rb:8:9: C: Cyclomatic complexity for call is too high. [7/6]
        def call(message, backtrace, options = {}, env = nil, original_exception = nil)
        ^^^
lib/grape-active_model_serializers/error_formatter.rb:8:81: C: Line is too long. [87/80]
        def call(message, backtrace, options = {}, env = nil, original_exception = nil)
                                                                                ^^^^^^^

31 files inspected, 2 offenses detected
Inspecting 31 files
..CCCCC.C.......C..............

Offenses:

lib/grape-active_model_serializers/endpoint_extension.rb:8:3: C: Missing top-level module documentation comment.
  module EndpointExtension
  ^^^^^^
lib/grape-active_model_serializers/error_formatter.rb:4:5: C: Missing top-level module documentation comment.
    module ActiveModelSerializers
    ^^^^^^
lib/grape-active_model_serializers/error_formatter.rb:8:9: C: Cyclomatic complexity for call is too high. [7/6]
        def call(message, backtrace, options = {}, env = nil, original_exception = nil)
        ^^^
lib/grape-active_model_serializers/error_formatter.rb:8:81: C: Line is too long. [87/80]
        def call(message, backtrace, options = {}, env = nil, original_exception = nil)
                                                                                ^^^^^^^
lib/grape-active_model_serializers/formatter.rb:3:5: C: Missing top-level module documentation comment.
    module ActiveModelSerializers
    ^^^^^^
lib/grape-active_model_serializers/options_builder.rb:3:5: C: Missing top-level class documentation comment.
    class OptionsBuilder
    ^^^^^
lib/grape-active_model_serializers/serializer_resolver.rb:3:5: C: Missing top-level class documentation comment.
    class SerializerResolver
    ^^^^^
lib/grape-active_model_serializers.rb:1:1: C: The name of this source file (grape-active_model_serializers.rb) should use snake_case.
require 'active_model_serializers'
^
spec/grape-active_model_serializers_spec.rb:1:1: C: The name of this source file (grape-active_model_serializers_spec.rb) should use snake_case.
require 'spec_helper'
^

31 files inspected, 9 offenses detected
Created .rubocop_todo.yml.
Run `rubocop --config .rubocop_todo.yml`, or add `inherit_from: .rubocop_todo.yml` in a .rubocop.yml file.```

Copy link
Member

@dblock dblock Oct 3, 2017

Choose a reason for hiding this comment

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

Yes, and now Rubocop will run clean, commit the changed files.

@xn
Copy link
Contributor Author

xn commented Oct 5, 2017

kk, constraining to 1.0 works, but breaks the others.

@dblock
Copy link
Member

dblock commented Oct 8, 2017

Oh I see. Make this conditional, in the case Grape::JSON is defined you can use that, otherwise use MultiJson, which was required in older versions of Grape.

@xn
Copy link
Contributor Author

xn commented Oct 9, 2017

Finally! I think this is ready to go.

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.

My only must have is that multi_json dependency, please.

@@ -18,6 +18,7 @@ Gem::Specification.new do |gem|

gem.add_dependency 'grape', '>= 0.8.0'
gem.add_dependency 'active_model_serializers', '>= 0.10.0'
gem.add_dependency 'multi_json', '~> 1.0'
Copy link
Member

Choose a reason for hiding this comment

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

So, this one should still be removed, it's unnecessary in all Grape versions since it's either coming via Grape or is not used..


class << self
def call(message, backtrace, options = {}, env = nil, original_exception = nil)
result = if respond_to? :present
Copy link
Member

Choose a reason for hiding this comment

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

Nitpick, might be shorter and more concise, but not a must have.

message = present(message) if respond_to?(:present)
message = wrap_message(message)
message = ...

let(:app) { Class.new(Grape::API) }

before do
ActiveModel::Serializer.config.adapter = :json_api
Copy link
Member

Choose a reason for hiding this comment

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

This pollutes future tests, so should either be set for all tests or unset in after.


before do
ActiveModel::Serializer.config.adapter = :json_api
app.format :json
Copy link
Member

Choose a reason for hiding this comment

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

Move this into the let, so

let(:app) {
   Class.new(Grape::API) do
      formatter ...
      ...
   end
}

describe '#call' do
context 'message is an activemodel' do
let(:message) {
class Foo
Copy link
Member

Choose a reason for hiding this comment

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

This globally defines a class Foo. It should be a Class.new as well.

Foo.new(name: 'bar')
}
it 'formats the error' do
result = subject
Copy link
Member

Choose a reason for hiding this comment

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

This is shared with the example below and should be moved to a let as well.

@xn
Copy link
Contributor Author

xn commented Oct 17, 2017

This should be it.

@dblock
Copy link
Member

dblock commented Oct 17, 2017

Code looks great. You still have to add something to README!

@xn
Copy link
Contributor Author

xn commented Oct 17, 2017

Would this work?

Tell your API to use Grape::Formatter::ActiveModelSerializers

class API < Grape::API
  format :json
  formatter :json, Grape::Formatter::ActiveModelSerializers

  # Serializes errors with ActiveModel::Serializer::ErrorSerializer if an ActiveModel.
  # Serializer conforms to format. ex: json, jsonapi
  error_formatter :json, Grape::Formatter::ActiveModelSerializers
end

@dblock
Copy link
Member

dblock commented Oct 18, 2017

Something like that, an explain what these output.

@xn
Copy link
Contributor Author

xn commented Oct 18, 2017

You want me to document the behavior of ActiveModel::Serializer::ErrorSerializer?

@dblock
Copy link
Member

dblock commented Oct 18, 2017

Yes, something should explain what's happening with this new code that wasn't happening before.

@xn
Copy link
Contributor Author

xn commented Oct 19, 2017

Does this work?

class API < Grape::API
  format :json
  formatter :json, Grape::Formatter::ActiveModelSerializers

  # Serializes errors with ActiveModel::Serializer::ErrorSerializer if an ActiveModel.
  # Serializer conforms to the adapter, ex: json, jsonapi.
  # So an error formatted with a jsonapi formatter would render as per:
  # http://jsonapi.org/format/#error-objects
  error_formatter :json, Grape::Formatter::ActiveModelSerializers
end

@dblock
Copy link
Member

dblock commented Oct 19, 2017

Great! As long as there's something in the README.

@xn
Copy link
Contributor Author

xn commented Oct 20, 2017

That is from the readme.

@xn
Copy link
Contributor Author

xn commented Oct 20, 2017

Under: Tell your API to use Grape::Formatter::ActiveModelSerializers

@dblock
Copy link
Member

dblock commented Oct 20, 2017

Oh you're saying we documented it but it was never implemented (sorry, I'm just cheerleading this repo :)).

I'll just merge this, any interest in doing the next release and helping out with this project?

@dblock dblock merged commit b265419 into ruby-grape:master Oct 20, 2017
@dblock
Copy link
Member

dblock commented Oct 20, 2017

And thanks for hanging on with my many nitpicky comments!

@xn
Copy link
Contributor Author

xn commented Oct 22, 2017

No, that was a miscommunication. Let me do a quick PR for the Docs.

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.

None yet

2 participants