mirror of
https://github.com/samsonjs/grape-active_model_serializers.git
synced 2026-03-25 08:45:55 +00:00
add custom error formatter (#76)
This commit is contained in:
parent
fab476772e
commit
b2654190c1
6 changed files with 185 additions and 10 deletions
|
|
@ -1,20 +1,48 @@
|
|||
# This configuration was generated by `rubocop --auto-gen-config`
|
||||
# on 2015-01-13 18:47:14 -0500 using RuboCop version 0.28.0.
|
||||
# This configuration was generated by
|
||||
# `rubocop --auto-gen-config`
|
||||
# on 2017-10-09 10:22:52 -0500 using RuboCop version 0.41.2.
|
||||
# The point is for the user to remove these configuration records
|
||||
# one by one as the offenses are removed from the code base.
|
||||
# Note that changes in the inspected code, or installation of new
|
||||
# versions of RuboCop, may require this file to be generated again.
|
||||
|
||||
# Offense count: 25
|
||||
# Configuration parameters: AllowURI, URISchemes.
|
||||
# Offense count: 1
|
||||
Metrics/AbcSize:
|
||||
Max: 20
|
||||
Max: 18
|
||||
|
||||
# Offense count: 7
|
||||
# Offense count: 1
|
||||
Metrics/CyclomaticComplexity:
|
||||
Max: 9
|
||||
|
||||
# Offense count: 1
|
||||
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes.
|
||||
# URISchemes: http, https
|
||||
Metrics/LineLength:
|
||||
Max: 87
|
||||
|
||||
# Offense count: 1
|
||||
# Configuration parameters: CountComments.
|
||||
Metrics/MethodLength:
|
||||
Max: 18
|
||||
|
||||
# Offense count: 1
|
||||
Metrics/PerceivedComplexity:
|
||||
Max: 11
|
||||
|
||||
# Offense count: 5
|
||||
Style/Documentation:
|
||||
Enabled: false
|
||||
Exclude:
|
||||
- 'spec/**/*'
|
||||
- 'test/**/*'
|
||||
- 'lib/grape-active_model_serializers/endpoint_extension.rb'
|
||||
- 'lib/grape-active_model_serializers/error_formatter.rb'
|
||||
- 'lib/grape-active_model_serializers/formatter.rb'
|
||||
- 'lib/grape-active_model_serializers/options_builder.rb'
|
||||
- 'lib/grape-active_model_serializers/serializer_resolver.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# Configuration parameters: Exclude.
|
||||
# Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts.
|
||||
Style/FileName:
|
||||
Enabled: false
|
||||
Exclude:
|
||||
- 'lib/grape-active_model_serializers.rb'
|
||||
- 'spec/grape-active_model_serializers_spec.rb'
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
### 1.5.2 (Next)
|
||||
|
||||
* [#76](https://github.com/ruby-grape/grape-active_model_serializers/pull/76): Add custom error formatter - [@xn](https://github.com/xn).
|
||||
* Your contribution here.
|
||||
|
||||
### 1.5.1 (April 25, 2017)
|
||||
|
|
|
|||
2
Gemfile
2
Gemfile
|
|
@ -2,7 +2,7 @@ source 'https://rubygems.org'
|
|||
|
||||
gemspec
|
||||
|
||||
case version = ENV['GRAPE_VERSION'] || '~> 0.10.0'
|
||||
case version = ENV['GRAPE_VERSION'] || '~> 1.0.0'
|
||||
when 'HEAD'
|
||||
gem 'grape', github: 'intridea/grape'
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
require 'active_model_serializers'
|
||||
require 'grape'
|
||||
require 'grape-active_model_serializers/endpoint_extension'
|
||||
require 'grape-active_model_serializers/error_formatter'
|
||||
require 'grape-active_model_serializers/formatter'
|
||||
require 'grape-active_model_serializers/serializer_resolver'
|
||||
require 'grape-active_model_serializers/options_builder'
|
||||
|
|
|
|||
53
lib/grape-active_model_serializers/error_formatter.rb
Normal file
53
lib/grape-active_model_serializers/error_formatter.rb
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
module Grape
|
||||
module ErrorFormatter
|
||||
module ActiveModelSerializers
|
||||
extend Base
|
||||
|
||||
class << self
|
||||
def call(message, backtrace, options = {}, env = nil, original_exception = nil)
|
||||
message = present(message, env) if respond_to?(:present)
|
||||
message = wrap_message(message)
|
||||
|
||||
rescue_options = options[:rescue_options] || {}
|
||||
if rescue_options[:backtrace] && backtrace && !backtrace.empty?
|
||||
message = message.merge(backtrace: backtrace)
|
||||
end
|
||||
if rescue_options[:original_exception] && original_exception
|
||||
message = message
|
||||
.merge(original_exception: original_exception.inspect)
|
||||
end
|
||||
if ::Grape.const_defined? :Json
|
||||
::Grape::Json.dump(message)
|
||||
else
|
||||
::MultiJson.dump(message)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def wrap_message(message)
|
||||
if active_model?(message)
|
||||
::ActiveModelSerializers::SerializableResource.new(
|
||||
message,
|
||||
serializer: ActiveModel::Serializer::ErrorSerializer
|
||||
).as_json
|
||||
elsif ok_to_pass_through?(message)
|
||||
message
|
||||
else
|
||||
{ error: message }
|
||||
end
|
||||
end
|
||||
|
||||
def active_model?(message)
|
||||
message.respond_to?(:errors) &&
|
||||
message.errors.is_a?(ActiveModel::Errors)
|
||||
end
|
||||
|
||||
def ok_to_pass_through?(message)
|
||||
message.is_a?(Exceptions::ValidationErrors) ||
|
||||
message.is_a?(Hash)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
92
spec/grape-active_model_serializers/error_formatter_spec.rb
Normal file
92
spec/grape-active_model_serializers/error_formatter_spec.rb
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
require 'spec_helper'
|
||||
require 'grape-active_model_serializers/error_formatter'
|
||||
|
||||
describe Grape::ErrorFormatter::ActiveModelSerializers do
|
||||
subject { Grape::ErrorFormatter::ActiveModelSerializers }
|
||||
let(:backtrace) { ['Line:1'] }
|
||||
let(:options) { Hash.new }
|
||||
let(:env) { { 'api.endpoint' => app.endpoints.first } }
|
||||
let(:original_exception) { StandardError.new('oh noes!') }
|
||||
|
||||
let(:app) {
|
||||
Class.new(Grape::API) do |app|
|
||||
app.format :json
|
||||
app.formatter :jsonapi, Grape::Formatter::ActiveModelSerializers
|
||||
app.error_formatter :jsonapi, Grape::ErrorFormatter::ActiveModelSerializers
|
||||
|
||||
app.namespace('space') do |ns|
|
||||
ns.get('/', root: false) do
|
||||
error!(message)
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
let(:foo) {
|
||||
Class.new {
|
||||
include ActiveModel::Model
|
||||
|
||||
attr_accessor :name
|
||||
|
||||
def initialize(attributes = {})
|
||||
super
|
||||
errors.add(:name, 'We don\'t like bears')
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
before do
|
||||
ActiveModel::Serializer.config.adapter = :json_api
|
||||
end
|
||||
|
||||
after do
|
||||
ActiveModel::Serializer.config.adapter = :json
|
||||
end
|
||||
|
||||
describe '#call' do
|
||||
context 'message is an activemodel' do
|
||||
let(:message) {
|
||||
foo.new(name: 'bar')
|
||||
}
|
||||
it 'formats the error' do
|
||||
result = subject
|
||||
.call(message, backtrace, options, env, original_exception)
|
||||
json_hash = JSON.parse(result)
|
||||
|
||||
expected_result = {
|
||||
'errors' => [
|
||||
{
|
||||
'source' => {
|
||||
'pointer' => '/data/attributes/name'
|
||||
},
|
||||
'detail' => 'We don\'t like bears'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
expect(json_hash == expected_result).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'message is hash like' do
|
||||
let(:message) { { 'errors' => ['error'] } }
|
||||
it 'passes the message through' do
|
||||
result = subject
|
||||
.call(message, backtrace, options, env, original_exception)
|
||||
json_hash = JSON.parse(result)
|
||||
|
||||
expect(json_hash == message).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'message is text' do
|
||||
let(:message) { 'error' }
|
||||
it 'wraps the error' do
|
||||
result = subject
|
||||
.call(message, backtrace, options, env, original_exception)
|
||||
json_hash = JSON.parse(result)
|
||||
|
||||
expect(json_hash == { 'error' => message }).to eq(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in a new issue