Skip to content

Commit c1c4023

Browse files
Merge pull request #2 from easyPEP/chore/fix-error-serialization
chore: fix error serialization for string errors
2 parents 6ff33ee + 8f3b8d5 commit c1c4023

4 files changed

Lines changed: 54 additions & 4 deletions

File tree

lib/jsonapi/active_model_error_serializer.rb

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ class ActiveModelErrorSerializer < ErrorSerializer
1313

1414
attribute :code do |object|
1515
_, error_hash = object
16-
code = error_hash[:error] unless error_hash[:error].is_a?(Hash)
16+
unless error_hash[:error].is_a?(Hash) || error_hash[:error].is_a?(String)
17+
code = error_hash[:error]
18+
end
1719
code ||= error_hash[:message] || :invalid
1820
# `parameterize` separator arguments are different on Rails 4 vs 5...
1921
code.to_s.delete("''").parameterize.tr('-', '_')
@@ -29,9 +31,15 @@ class ActiveModelErrorSerializer < ErrorSerializer
2931
error_key, nil, error_hash[:error]
3032
)
3133
elsif error_hash[:error].present?
32-
message = errors_object.generate_message(
33-
error_key, error_hash[:error], error_hash
34-
)
34+
# if the error was added as a string, we do not need to generate an
35+
# error message, but use the error as is
36+
if error_hash[:error].is_a?(String)
37+
message = error_hash[:error]
38+
else
39+
message = errors_object.generate_message(
40+
error_key, error_hash[:error], error_hash
41+
)
42+
end
3543
else
3644
message = error_hash[:message]
3745
end

spec/dummy.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,21 @@ class Note < ActiveRecord::Base
4343
validates_format_of :title, without: /BAD_TITLE/
4444
validates_numericality_of :quantity, less_than: 100, if: :quantity?
4545
belongs_to :user, required: true
46+
47+
validate :nice_title
48+
49+
# this validation is added to test that a validation error added as a string
50+
# (instead of a symbol) works as well
51+
#
52+
# see https://api.rubyonrails.org/v7.0.8.7/classes/ActiveModel/Errors.html#method-i-add
53+
#
54+
# > If `type` is a string, it will be used as error message.
55+
#
56+
def nice_title
57+
return unless title == 'NOT_SO_NICE_TITLE'
58+
59+
errors.add(:title, 'is not so nice')
60+
end
4661
end
4762

4863
class CustomNoteSerializer

spec/errors_spec.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,27 @@
119119
end
120120
end
121121

122+
context 'with a validation error type that is a string' do
123+
let(:params) do
124+
payload = note_params.dup
125+
payload[:data][:attributes][:title] = 'NOT_SO_NICE_TITLE'
126+
payload
127+
end
128+
129+
it do
130+
expect(response).to have_http_status(:unprocessable_entity)
131+
expect(response_json['errors'].size).to eq(2)
132+
expect(response_json['errors'][0]['status']).to eq('422')
133+
expect(response_json['errors'][0]['code']).to include('invalid')
134+
expect(response_json['errors'][0]['title'])
135+
.to eq(Rack::Utils::HTTP_STATUS_CODES[422])
136+
expect(response_json['errors'][0]['source'])
137+
.to eq('pointer' => '/data/attributes/title')
138+
expect(response_json['errors'][0]['detail'])
139+
.to eq('Title is not so nice')
140+
end
141+
end
142+
122143
context 'as a param attribute' do
123144
let(:params) do
124145
payload = note_params.dup

spec/pagination_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,16 @@
5353

5454
context 'on page 2 out of 3' do
5555
let(:as_list) { }
56+
# .compact_blank is not available in our Rails version
57+
# rubocop:disable Rails/CompactBlank
5658
let(:params) do
5759
{
5860
page: { number: 2, size: 1 },
5961
sort: '-created_at',
6062
as_list: as_list
6163
}.reject { |_k, _v| _v.blank? }
6264
end
65+
# rubocop:enable Rails/CompactBlank
6366

6467
context 'on an array of resources' do
6568
let(:as_list) { true }
@@ -153,12 +156,15 @@
153156

154157
context 'on paging beyond the last page' do
155158
let(:as_list) { }
159+
# .compact_blank is not available in our Rails version
160+
# rubocop:disable Rails/CompactBlank
156161
let(:params) do
157162
{
158163
page: { number: 5, size: 1 },
159164
as_list: as_list
160165
}.reject { |_k, _v| _v.blank? }
161166
end
167+
# rubocop:enable Rails/CompactBlank
162168

163169
context 'on an array of resources' do
164170
let(:as_list) { true }

0 commit comments

Comments
 (0)