human_error 1.13.4 → 2.0.0beta2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|