human_error 1.13.4 → 2.0.0beta2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/human_error/errors/crud_errors/association_error.rb +19 -0
- data/lib/human_error/errors/crud_errors/resource_not_found_error.rb +20 -0
- data/lib/human_error/errors/crud_errors/resource_persistence_error.rb +16 -0
- data/lib/human_error/rescuable_resource.rb +24 -32
- data/lib/human_error/version.rb +1 -1
- data/lib/human_error.rb +13 -3
- data/spec/lib/human_error/errors/crud_errors/association_error_spec.rb +26 -1
- data/spec/lib/human_error/errors/crud_errors/resource_not_found_error_spec.rb +44 -2
- data/spec/lib/human_error/errors/crud_errors/resource_persistence_error_spec.rb +47 -2
- data/spec/lib/human_error_spec.rb +9 -4
- metadata +7 -8
- data/lib/human_error/persistable.rb +0 -56
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 38bd2094b46916777e66209fd09752aec12782c6
|
4
|
+
data.tar.gz: 5e8539f5cf3898079f28f3a6014aca66f7d09d79
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7395626c161f3012d42c7cf0de4d934bf77cf34447bb192d4b06f004efc80e11dfbd6f910cb7b1efb4a5c53759f4a114e5f535242d32073a3e2714eb83cea386
|
7
|
+
data.tar.gz: b1dbf433d0e8725ef3ac2192dc2bb6afc8e3bc49078eb43fd5309334959d0ac76b58fa41f1b9426189309304c4ca391686c32d9a62ea207f2654c9c51a74aa50
|
@@ -10,6 +10,25 @@ class AssociationError < RequestError
|
|
10
10
|
:association_id,
|
11
11
|
:attributes
|
12
12
|
|
13
|
+
def self.convert(original_error, overrides = {})
|
14
|
+
initialization_parameters = {}
|
15
|
+
|
16
|
+
case original_error.class.name
|
17
|
+
when 'ActiveRecord::InvalidForeignKey'
|
18
|
+
message_info_pattern = /DETAIL: Key \((.*)_id\)=\(([a-f0-9\-]+)\)/
|
19
|
+
message_info = original_error.
|
20
|
+
message.
|
21
|
+
match(message_info_pattern)[1..-1]
|
22
|
+
|
23
|
+
initialization_parameters = {
|
24
|
+
association_name: message_info[0],
|
25
|
+
association_id: message_info[1],
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
new(initialization_parameters.merge(overrides))
|
30
|
+
end
|
31
|
+
|
13
32
|
def http_status
|
14
33
|
422
|
15
34
|
end
|
@@ -6,6 +6,26 @@ module Errors
|
|
6
6
|
class ResourceNotFoundError < RequestError
|
7
7
|
include CrudError
|
8
8
|
|
9
|
+
def self.convert(original_error, overrides = {})
|
10
|
+
initialization_parameters = {}
|
11
|
+
|
12
|
+
case original_error.class.name
|
13
|
+
when 'ActiveRecord::RecordNotFound'
|
14
|
+
initialization_parameters = {
|
15
|
+
resource_id: case original_error.message
|
16
|
+
when /\ACouldn't find .* without an ID\z/
|
17
|
+
[]
|
18
|
+
when /\ACouldn't find .* with \'.*\'=([a-f0-9\-]+)/
|
19
|
+
[Regexp.last_match(1)]
|
20
|
+
when /\ACouldn't find all .* with \'.*\': ((?:[a-f0-9\-]+(?:, )?)+)/
|
21
|
+
Array(Regexp.last_match(1).split(', '))
|
22
|
+
end,
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
new(initialization_parameters.merge(overrides))
|
27
|
+
end
|
28
|
+
|
9
29
|
def http_status
|
10
30
|
404
|
11
31
|
end
|
@@ -9,6 +9,22 @@ class ResourcePersistenceError < RequestError
|
|
9
9
|
attr_accessor :errors,
|
10
10
|
:attributes
|
11
11
|
|
12
|
+
def self.convert(original_error, overrides = {})
|
13
|
+
initialization_parameters = {}
|
14
|
+
|
15
|
+
case original_error.class.name
|
16
|
+
when 'ActiveRecord::RecordInvalid',
|
17
|
+
'ActiveRecord::RecordNotSaved'
|
18
|
+
|
19
|
+
initialization_parameters = {
|
20
|
+
attributes: original_error.record.attributes,
|
21
|
+
errors: original_error.record.errors.full_messages,
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
new(initialization_parameters.merge(overrides))
|
26
|
+
end
|
27
|
+
|
12
28
|
def http_status
|
13
29
|
422
|
14
30
|
end
|
@@ -6,49 +6,41 @@ class HumanError
|
|
6
6
|
module RescuableResource
|
7
7
|
module ClassMethods
|
8
8
|
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Style/GuardClause
|
9
|
-
def rescue_resource(
|
10
|
-
|
9
|
+
def rescue_resource(resource_name, from:, via:)
|
10
|
+
resource_class_name = resource_name.classify
|
11
|
+
lookup_library = via
|
11
12
|
|
12
13
|
if from.include? 'persistence'
|
13
|
-
rescue_from
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
render json: error,
|
22
|
-
status: error.http_status
|
14
|
+
rescue_from 'ActiveRecord::RecordInvalid',
|
15
|
+
'ActiveRecord::RecordNotSaved' do |exception|
|
16
|
+
human_error = lookup_library.convert(exception,
|
17
|
+
resource_name: resource_class_name,
|
18
|
+
action: action_name)
|
19
|
+
|
20
|
+
render json: human_error,
|
21
|
+
status: human_error.http_status
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
26
25
|
if from.include? 'not_found'
|
27
|
-
rescue_from
|
28
|
-
|
26
|
+
rescue_from 'ActiveRecord::RecordNotFound' do |exception|
|
27
|
+
human_error = lookup_library.convert(exception,
|
28
|
+
resource_name: resource_class_name,
|
29
|
+
action: action_name)
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
resource_name: e.resource_name,
|
33
|
-
resource_id: resource_id,
|
34
|
-
action: action_name)
|
35
|
-
|
36
|
-
render json: error,
|
37
|
-
status: error.http_status
|
31
|
+
render json: human_error,
|
32
|
+
status: human_error.http_status
|
38
33
|
end
|
39
34
|
end
|
40
35
|
|
41
36
|
if from.include? 'association'
|
42
|
-
rescue_from
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
render json: error,
|
51
|
-
status: error.http_status
|
37
|
+
rescue_from 'ActiveRecord::InvalidForeignKey' do |exception|
|
38
|
+
human_error = lookup_library.convert(exception,
|
39
|
+
resource_name: resource_class_name,
|
40
|
+
action: action_name)
|
41
|
+
|
42
|
+
render json: human_error,
|
43
|
+
status: human_error.http_status
|
52
44
|
end
|
53
45
|
end
|
54
46
|
end
|
data/lib/human_error/version.rb
CHANGED
data/lib/human_error.rb
CHANGED
@@ -11,9 +11,19 @@ class HumanError
|
|
11
11
|
yield configuration if block_given?
|
12
12
|
end
|
13
13
|
|
14
|
-
def fetch(error_type, **
|
15
|
-
Object.const_get("HumanError::Errors::#{error_type}")
|
16
|
-
|
14
|
+
def fetch(error_type, **_args)
|
15
|
+
Object.const_get("HumanError::Errors::#{error_type}")
|
16
|
+
end
|
17
|
+
|
18
|
+
def convert(original_error, overrides = {})
|
19
|
+
overrides = configuration.to_h.merge(overrides)
|
20
|
+
|
21
|
+
case original_error.class.name
|
22
|
+
when 'ActiveRecord::InvalidForeignKey'
|
23
|
+
fetch('AssociationError').convert(original_error, overrides)
|
24
|
+
when 'ActiveRecord::RecordNotFound'
|
25
|
+
fetch('ResourceNotFoundError').convert(original_error, overrides)
|
26
|
+
end
|
17
27
|
end
|
18
28
|
|
19
29
|
def raise(error_type, **args)
|
@@ -1,20 +1,29 @@
|
|
1
1
|
require 'rspectacular'
|
2
2
|
require 'human_error/errors/crud_errors/association_error'
|
3
|
+
require 'active_record/errors'
|
3
4
|
|
4
5
|
class HumanError
|
5
6
|
module Errors
|
6
7
|
describe AssociationError do
|
7
|
-
let(:
|
8
|
+
let(:foreign_key_error) do
|
9
|
+
ActiveRecord::InvalidForeignKey.new('DETAIL: Key (resource_id)=(123)')
|
10
|
+
end
|
8
11
|
|
9
12
|
it 'has a status of 422' do
|
13
|
+
error = AssociationError.new
|
14
|
+
|
10
15
|
expect(error.http_status).to eql 422
|
11
16
|
end
|
12
17
|
|
13
18
|
it 'has a code of 1009' do
|
19
|
+
error = AssociationError.new
|
20
|
+
|
14
21
|
expect(error.code).to eql 1009
|
15
22
|
end
|
16
23
|
|
17
24
|
it 'has a knowledgebase article ID of 1234567890' do
|
25
|
+
error = AssociationError.new
|
26
|
+
|
18
27
|
expect(error.knowledgebase_article_id).to eql '1234567890'
|
19
28
|
end
|
20
29
|
|
@@ -46,6 +55,22 @@ describe AssociationError do
|
|
46
55
|
expect(error.friendly_message).to eql 'Sorry! There was a problem when we tried to ' \
|
47
56
|
'set the black leather trenchcoat on that Neo.'
|
48
57
|
end
|
58
|
+
|
59
|
+
it 'can convert an "ActiveRecord::InvalidForeignKey"' do
|
60
|
+
error = AssociationError.convert(foreign_key_error)
|
61
|
+
|
62
|
+
expect(error.resource_name).to eql nil
|
63
|
+
expect(error.association_name).to eql 'resource'
|
64
|
+
expect(error.association_id).to eql '123'
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'can convert an "ActiveRecord::InvalidForeignKey" while overriding attributes' do
|
68
|
+
error = AssociationError.convert(foreign_key_error, resource_name: 'my_resource')
|
69
|
+
|
70
|
+
expect(error.resource_name).to eql 'my_resource'
|
71
|
+
expect(error.association_name).to eql 'resource'
|
72
|
+
expect(error.association_id).to eql '123'
|
73
|
+
end
|
49
74
|
end
|
50
75
|
end
|
51
76
|
end
|
@@ -1,20 +1,25 @@
|
|
1
1
|
require 'rspectacular'
|
2
2
|
require 'human_error/errors/crud_errors/resource_not_found_error'
|
3
|
+
require 'active_record/errors'
|
3
4
|
|
4
5
|
class HumanError
|
5
6
|
module Errors
|
6
7
|
describe ResourceNotFoundError do
|
7
|
-
let(:error) { ResourceNotFoundError.new }
|
8
|
-
|
9
8
|
it 'has a status of 404' do
|
9
|
+
error = ResourceNotFoundError.new
|
10
|
+
|
10
11
|
expect(error.http_status).to eql 404
|
11
12
|
end
|
12
13
|
|
13
14
|
it 'has a code of 1005' do
|
15
|
+
error = ResourceNotFoundError.new
|
16
|
+
|
14
17
|
expect(error.code).to eql 1005
|
15
18
|
end
|
16
19
|
|
17
20
|
it 'has a knowledgebase article ID of 1234567890' do
|
21
|
+
error = ResourceNotFoundError.new
|
22
|
+
|
18
23
|
expect(error.knowledgebase_article_id).to eql '1234567890'
|
19
24
|
end
|
20
25
|
|
@@ -49,6 +54,43 @@ describe ResourceNotFoundError do
|
|
49
54
|
expect(error.friendly_message).to eql 'Sorry! The black leather trenchcoat you ' \
|
50
55
|
'tried to bullet time does not exist.'
|
51
56
|
end
|
57
|
+
|
58
|
+
it 'can convert an "ActiveRecord::RecordNotFound" with no IDs' do
|
59
|
+
record_not_found_error = ActiveRecord::RecordNotFound.new \
|
60
|
+
"Couldn't find resource without an ID"
|
61
|
+
error = ResourceNotFoundError.convert(record_not_found_error)
|
62
|
+
|
63
|
+
expect(error.resource_name).to eql nil
|
64
|
+
expect(error.resource_id).to eql []
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'can convert an "ActiveRecord::RecordNotFound" with one ID' do
|
68
|
+
record_not_found_error = ActiveRecord::RecordNotFound.new \
|
69
|
+
"Couldn't find resource with 'id'=123"
|
70
|
+
error = ResourceNotFoundError.convert(record_not_found_error)
|
71
|
+
|
72
|
+
expect(error.resource_name).to eql nil
|
73
|
+
expect(error.resource_id).to eql %w{123}
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'can convert an "ActiveRecord::RecordNotFound" with multiple IDs' do
|
77
|
+
record_not_found_error = ActiveRecord::RecordNotFound.new \
|
78
|
+
"Couldn't find all resource with 'id': 123, 456, 789"
|
79
|
+
error = ResourceNotFoundError.convert(record_not_found_error)
|
80
|
+
|
81
|
+
expect(error.resource_name).to eql nil
|
82
|
+
expect(error.resource_id).to eql %w{123 456 789}
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'can convert an "ActiveRecord::RecordNotFound" while overriding attributes' do
|
86
|
+
record_not_found_error = ActiveRecord::RecordNotFound.new \
|
87
|
+
"Couldn't find resource with 'id'=123"
|
88
|
+
error = ResourceNotFoundError.convert(record_not_found_error,
|
89
|
+
resource_name: 'my_resource')
|
90
|
+
|
91
|
+
expect(error.resource_name).to eql 'my_resource'
|
92
|
+
expect(error.resource_id).to eql %w{123}
|
93
|
+
end
|
52
94
|
end
|
53
95
|
end
|
54
96
|
end
|
@@ -1,20 +1,43 @@
|
|
1
1
|
require 'rspectacular'
|
2
2
|
require 'human_error/errors/crud_errors/resource_persistence_error'
|
3
|
+
require 'active_support'
|
4
|
+
require 'active_model'
|
5
|
+
require 'active_record/errors'
|
6
|
+
require 'active_record/validations'
|
7
|
+
|
8
|
+
class HumanErrorTestModel
|
9
|
+
include ActiveModel::Model
|
10
|
+
include ActiveModel::AttributeMethods
|
11
|
+
|
12
|
+
attr_accessor :some_attribute
|
13
|
+
|
14
|
+
validates_presence_of :some_attribute
|
15
|
+
|
16
|
+
def attributes
|
17
|
+
{
|
18
|
+
'some_attribute' => @some_attribute,
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
3
22
|
|
4
23
|
class HumanError
|
5
24
|
module Errors
|
6
25
|
describe ResourcePersistenceError do
|
7
|
-
let(:error) { ResourcePersistenceError.new }
|
8
|
-
|
9
26
|
it 'has a status of 422' do
|
27
|
+
error = ResourcePersistenceError.new
|
28
|
+
|
10
29
|
expect(error.http_status).to eql 422
|
11
30
|
end
|
12
31
|
|
13
32
|
it 'has a code of 1006' do
|
33
|
+
error = ResourcePersistenceError.new
|
34
|
+
|
14
35
|
expect(error.code).to eql 1006
|
15
36
|
end
|
16
37
|
|
17
38
|
it 'has a knowledgebase article ID of 1234567890' do
|
39
|
+
error = ResourcePersistenceError.new
|
40
|
+
|
18
41
|
expect(error.knowledgebase_article_id).to eql '1234567890'
|
19
42
|
end
|
20
43
|
|
@@ -42,6 +65,28 @@ describe ResourcePersistenceError do
|
|
42
65
|
expect(error.friendly_message).to eql 'Sorry! We had a problem when tried to ' \
|
43
66
|
'bullet time that black leather trenchcoat.'
|
44
67
|
end
|
68
|
+
|
69
|
+
it 'can convert an "ActiveRecord::RecordNotSaved"' do
|
70
|
+
record = HumanErrorTestModel.new
|
71
|
+
record.valid?
|
72
|
+
resource_persistence_error = ActiveRecord::RecordNotSaved.new('message', record)
|
73
|
+
error = ResourcePersistenceError.
|
74
|
+
convert(resource_persistence_error)
|
75
|
+
|
76
|
+
expect(error.attributes).to eql('some_attribute' => nil)
|
77
|
+
expect(error.errors).to eql ["Some attribute can't be blank"]
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'can convert an "ActiveRecord::RecordInvalid"' do
|
81
|
+
record = HumanErrorTestModel.new
|
82
|
+
record.valid?
|
83
|
+
resource_persistence_error = ActiveRecord::RecordInvalid.new(record)
|
84
|
+
error = ResourcePersistenceError.
|
85
|
+
convert(resource_persistence_error)
|
86
|
+
|
87
|
+
expect(error.attributes).to eql('some_attribute' => nil)
|
88
|
+
expect(error.errors).to eql ["Some attribute can't be blank"]
|
89
|
+
end
|
45
90
|
end
|
46
91
|
end
|
47
92
|
end
|
@@ -1,7 +1,12 @@
|
|
1
1
|
require 'rspectacular'
|
2
2
|
require 'human_error'
|
3
|
+
require 'active_record/errors'
|
3
4
|
|
4
5
|
describe HumanError do
|
6
|
+
let(:original_error) do
|
7
|
+
ActiveRecord::RecordNotFound.new("Couldn't find resource with 'id'=3")
|
8
|
+
end
|
9
|
+
|
5
10
|
it 'can create an instance of HumanError' do
|
6
11
|
expect(HumanError.new).to be_a HumanError
|
7
12
|
end
|
@@ -17,7 +22,7 @@ describe HumanError do
|
|
17
22
|
it 'can lookup errors' do
|
18
23
|
human_error = HumanError.new
|
19
24
|
|
20
|
-
expect(human_error.fetch('RequestError')).to
|
25
|
+
expect(human_error.fetch('RequestError')).to eql HumanError::Errors::RequestError
|
21
26
|
end
|
22
27
|
|
23
28
|
it 'can lookup errors based on the local configuration' do
|
@@ -25,7 +30,7 @@ describe HumanError do
|
|
25
30
|
config.api_version = 'foo'
|
26
31
|
end
|
27
32
|
|
28
|
-
fetched_error = human_error.
|
33
|
+
fetched_error = human_error.convert(original_error)
|
29
34
|
|
30
35
|
expect(fetched_error.api_version).to eql 'foo'
|
31
36
|
end
|
@@ -41,7 +46,7 @@ describe HumanError do
|
|
41
46
|
config.api_version = 'foo'
|
42
47
|
end
|
43
48
|
|
44
|
-
fetched_error = human_error.
|
49
|
+
fetched_error = human_error.convert(original_error)
|
45
50
|
|
46
51
|
expect(fetched_error.api_version).to eql 'foo'
|
47
52
|
end
|
@@ -53,7 +58,7 @@ describe HumanError do
|
|
53
58
|
config.api_version = 'foo'
|
54
59
|
end
|
55
60
|
|
56
|
-
fetched_error = human_error.
|
61
|
+
fetched_error = human_error.convert(original_error, api_version: 'bar')
|
57
62
|
|
58
63
|
expect(fetched_error.api_version).to eql 'bar'
|
59
64
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: human_error
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0beta2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jfelchner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-04-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -39,19 +39,19 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0.50'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: activerecord
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: '4.1'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: '4.1'
|
55
55
|
description: ''
|
56
56
|
email: accounts+git@thekompanee.com
|
57
57
|
executables: []
|
@@ -76,7 +76,6 @@ files:
|
|
76
76
|
- lib/human_error/errors/crud_errors/resource_persistence_error.rb
|
77
77
|
- lib/human_error/errors/request_error.rb
|
78
78
|
- lib/human_error/knowledgebase_id_directory.rb
|
79
|
-
- lib/human_error/persistable.rb
|
80
79
|
- lib/human_error/rescuable_resource.rb
|
81
80
|
- lib/human_error/utilities/string.rb
|
82
81
|
- lib/human_error/version.rb
|
@@ -106,9 +105,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
106
105
|
version: '0'
|
107
106
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
107
|
requirements:
|
109
|
-
- - "
|
108
|
+
- - ">"
|
110
109
|
- !ruby/object:Gem::Version
|
111
|
-
version:
|
110
|
+
version: 1.3.1
|
112
111
|
requirements: []
|
113
112
|
rubyforge_project:
|
114
113
|
rubygems_version: 2.4.6
|
@@ -1,56 +0,0 @@
|
|
1
|
-
class HumanError
|
2
|
-
module Persistable
|
3
|
-
module ClassMethods
|
4
|
-
def find(*ids)
|
5
|
-
super
|
6
|
-
rescue ActiveRecord::RecordNotFound => e
|
7
|
-
ids = case e.message
|
8
|
-
when /\ACouldn't find .* without an ID\z/
|
9
|
-
[]
|
10
|
-
when /\ACouldn't find .* with \'.*\'=([a-f0-9\-]+)/
|
11
|
-
[Regexp.last_match(1)]
|
12
|
-
when /\ACouldn't find all .* with \'.*\': ((?:[a-f0-9\-]+(?:, )?)+)/
|
13
|
-
Regexp.last_match(1).split(', ')
|
14
|
-
end
|
15
|
-
|
16
|
-
raise HumanError::Errors::ResourceNotFoundError.new(
|
17
|
-
resource_name: Persistable.human_error_resource_name(self),
|
18
|
-
resource_id: ids)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def save!(*args)
|
23
|
-
super
|
24
|
-
rescue ActiveRecord::InvalidForeignKey => e
|
25
|
-
association_info_pattern = /DETAIL: Key \((.*)_id\)=\(([a-f0-9\-]+)\)/
|
26
|
-
association_name, association_id = e.message.
|
27
|
-
match(association_info_pattern) \
|
28
|
-
[1..-1]
|
29
|
-
|
30
|
-
raise HumanError::Errors::AssociationError.new(
|
31
|
-
resource_name: Persistable.human_error_resource_name(self.class),
|
32
|
-
association_name: association_name,
|
33
|
-
association_id: association_id,
|
34
|
-
attributes: attributes)
|
35
|
-
rescue ActiveRecord::RecordInvalid, ActiveRecord::RecordNotSaved
|
36
|
-
raise HumanError::Errors::ResourcePersistenceError.new(
|
37
|
-
resource_name: Persistable.human_error_resource_name(self.class),
|
38
|
-
attributes: attributes,
|
39
|
-
errors: errors.full_messages)
|
40
|
-
end
|
41
|
-
|
42
|
-
def self.human_error_resource_name(klass)
|
43
|
-
last_part_of_class_name = /::(\w+)\z/
|
44
|
-
|
45
|
-
klass.
|
46
|
-
name[last_part_of_class_name, 1].
|
47
|
-
underscore.
|
48
|
-
humanize.
|
49
|
-
downcase
|
50
|
-
end
|
51
|
-
|
52
|
-
def self.included(base)
|
53
|
-
base.extend ClassMethods
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|