coaster 0.5.7 → 1.0.4
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/coaster/core_ext/object_translation.rb +6 -4
- data/lib/coaster/core_ext/standard_error.rb +57 -34
- data/lib/coaster/core_ext/standard_error/raven.rb +1 -1
- data/lib/coaster/version.rb +1 -1
- data/test/locales/en.yml +4 -0
- data/test/test_object_translation.rb +4 -0
- data/test/test_standard_error.rb +35 -20
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1efdff11e3158914f521590fb64642e9c1834987317b896db24896c31e772bcf
|
4
|
+
data.tar.gz: 3fcdb6480424ddcc27cc50c0568e6b8d9967bf494f8118d174d82e9072c03974
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 270b1faeeae2fe9fcccd3e0f2c4d9d8234c7d0288ee949ea29b7faac70e711e5394b2cb06b14da11a6e71fe770c46416e9e8e10fadca2303470171986e6a3911
|
7
|
+
data.tar.gz: c895e44a856beae32d2b46f09547d5c69aba008a46581ee096f9b069e6909251574f6dccf62f899fa3e51771e48acc1ad601f0a46e07a87cb5c8e59b706ea1f4
|
@@ -3,8 +3,9 @@ require 'i18n'
|
|
3
3
|
class Object
|
4
4
|
class << self
|
5
5
|
def _translate(*args)
|
6
|
-
options = args.last.is_a?(Hash) ? args.pop
|
6
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
7
7
|
options.merge!(_translate_params)
|
8
|
+
options = options.to_hash.symbolize_keys!
|
8
9
|
|
9
10
|
key = args.shift
|
10
11
|
subkey = nil
|
@@ -33,22 +34,22 @@ class Object
|
|
33
34
|
end
|
34
35
|
options[:tkey] ||= key
|
35
36
|
options.merge!(throw: true)
|
36
|
-
options.symbolize_keys!
|
37
37
|
result = catch(:exception) do
|
38
38
|
I18n.t(key, *args, options)
|
39
39
|
end
|
40
40
|
|
41
41
|
if result.is_a?(I18n::MissingTranslation)
|
42
|
-
Coaster.logger && Coaster.logger.warn(result)
|
43
42
|
unless options.key?(:original_missing)
|
44
43
|
options.merge!(original_missing: result)
|
45
44
|
end
|
46
45
|
|
47
46
|
if key_class.superclass == Object || key_class == Object
|
48
47
|
return options[:description] if options[:description].present?
|
48
|
+
Coaster.logger && Coaster.logger.warn(result)
|
49
49
|
throw :exception, result if options[:original_throw]
|
50
50
|
missing = options[:original_missing] || result
|
51
51
|
msg = missing.message
|
52
|
+
msg = msg.dup
|
52
53
|
msg.instance_variable_set(:@missing, missing)
|
53
54
|
msg.instance_variable_set(:@tkey, options[:tkey])
|
54
55
|
msg
|
@@ -57,6 +58,7 @@ class Object
|
|
57
58
|
_translate(subkey, *args, options)
|
58
59
|
end
|
59
60
|
else
|
61
|
+
result = result.dup if result.frozen?
|
60
62
|
result.instance_variable_set(:@translated, true)
|
61
63
|
result.instance_variable_set(:@tkey, options[:tkey])
|
62
64
|
result
|
@@ -74,7 +76,7 @@ class Object
|
|
74
76
|
# Foo::Bar.new._translate(:force) #=> ignore 'message' even if message exists
|
75
77
|
#
|
76
78
|
def _translate(*args)
|
77
|
-
options = args.last.is_a?(Hash) ? args.pop
|
79
|
+
options = (args.last.is_a?(Hash) ? args.pop : {}).with_indifferent_access
|
78
80
|
key = args.shift || (respond_to?(:tkey) ? tkey : nil)
|
79
81
|
|
80
82
|
if respond_to?(:description) && description.present? && description != 'false' && description != self.class.name
|
@@ -26,42 +26,43 @@ class StandardError
|
|
26
26
|
@tags = {}
|
27
27
|
@level = 'error'
|
28
28
|
@attributes = HashWithIndifferentAccess.new
|
29
|
+
@attributes.merge!(cause.attributes || {}) if cause && cause.respond_to?(:attributes)
|
29
30
|
@tkey = nil
|
30
31
|
|
31
32
|
case message
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
33
|
+
when Exception
|
34
|
+
msg = message
|
35
|
+
set_backtrace(message.backtrace)
|
36
|
+
when StandardError
|
37
|
+
@fingerprint = message.fingerprint
|
38
|
+
@tags = message.tags
|
39
|
+
@level = message.level
|
40
|
+
@tkey = message.tkey
|
41
|
+
@attributes = message.attributes
|
42
|
+
msg = message
|
43
|
+
set_backtrace(message.backtrace)
|
44
|
+
when Hash then
|
45
|
+
hash = message.with_indifferent_access rescue message
|
46
|
+
msg = hash.delete(:m)
|
47
|
+
msg = hash.delete(:msg) || msg
|
48
|
+
msg = hash.delete(:message) || msg
|
49
|
+
@fingerprint = hash.delete(:fingerprint) || hash.delete(:fingerprints)
|
50
|
+
@tags = hash.delete(:tags) || hash.delete(:tag)
|
51
|
+
@level = hash.delete(:level) || hash.delete(:severity) || @level
|
52
|
+
@tkey = hash.delete(:tkey)
|
53
|
+
msg = cause.message if msg.nil? && cause
|
54
|
+
@attributes.merge!(hash)
|
55
|
+
when String then
|
56
|
+
msg = message
|
57
|
+
when FalseClass, NilClass then
|
58
|
+
msg = ''
|
59
|
+
else
|
60
|
+
msg = message
|
60
61
|
end
|
61
62
|
|
62
63
|
@fingerprint = [] unless @fingerprint.is_a?(Array)
|
63
64
|
@tags = {} unless @tags.is_a?(Hash)
|
64
|
-
msg ||= self.class.
|
65
|
+
msg ||= self.class._translate
|
65
66
|
super(msg)
|
66
67
|
end
|
67
68
|
|
@@ -95,6 +96,14 @@ class StandardError
|
|
95
96
|
attributes[:http_status] = value
|
96
97
|
end
|
97
98
|
|
99
|
+
def report?
|
100
|
+
attributes.key?(:report) ? attributes[:report] : true
|
101
|
+
end
|
102
|
+
|
103
|
+
def intentional?
|
104
|
+
attributes[:intentional]
|
105
|
+
end
|
106
|
+
|
98
107
|
def code
|
99
108
|
attributes[:code] || status
|
100
109
|
end
|
@@ -114,6 +123,13 @@ class StandardError
|
|
114
123
|
end
|
115
124
|
alias_method :desc, :description
|
116
125
|
|
126
|
+
# more user friendly messages
|
127
|
+
def descriptions
|
128
|
+
return attributes[:descriptions] if attributes[:descriptions]
|
129
|
+
attributes[:descriptions] = {}
|
130
|
+
attributes[:descriptions]
|
131
|
+
end
|
132
|
+
|
117
133
|
def object
|
118
134
|
attributes[:object] || attributes[:obj]
|
119
135
|
end
|
@@ -124,7 +140,7 @@ class StandardError
|
|
124
140
|
end
|
125
141
|
|
126
142
|
def to_hash
|
127
|
-
hash =
|
143
|
+
hash = attributes.merge(
|
128
144
|
type: self.class.name, status: status,
|
129
145
|
http_status: http_status, message: message
|
130
146
|
)
|
@@ -190,16 +206,23 @@ class StandardError
|
|
190
206
|
end
|
191
207
|
|
192
208
|
def logging(options = {})
|
193
|
-
|
194
|
-
logger =
|
195
|
-
|
209
|
+
return unless report?
|
210
|
+
logger = nil
|
211
|
+
if defined?(Rails)
|
212
|
+
return if Rails.env.test? && intentional?
|
213
|
+
logger = Rails.logger
|
214
|
+
end
|
215
|
+
logger = options[:logger] || Coaster.logger || logger
|
216
|
+
return unless logger
|
196
217
|
|
197
218
|
cl = options[:cleaner] || cleaner
|
198
219
|
msg = to_detail
|
199
220
|
|
200
221
|
if cl && backtrace
|
222
|
+
bt = cl.clean(backtrace)
|
223
|
+
bt = bt[0..2] if intentional?
|
201
224
|
msg += "\tBACKTRACE:\n\t"
|
202
|
-
msg +=
|
225
|
+
msg += bt.join("\n\t")
|
203
226
|
end
|
204
227
|
|
205
228
|
if level && logger.respond_to?(level)
|
@@ -38,7 +38,7 @@ class StandardError
|
|
38
38
|
|
39
39
|
def capture(options = {})
|
40
40
|
return if options.key?(:report) && !options[:report]
|
41
|
-
return
|
41
|
+
return unless report?
|
42
42
|
nt = notes(options)
|
43
43
|
Raven.capture_exception(self, level: nt[:level]) do |event|
|
44
44
|
event.user.merge!(nt[:user] || {})
|
data/lib/coaster/version.rb
CHANGED
data/test/locales/en.yml
CHANGED
@@ -5,8 +5,12 @@ en:
|
|
5
5
|
SampleObject:
|
6
6
|
self: 'Coaster SampleObject Translated'
|
7
7
|
title: 'Coaster SampleObject Title (%{tkey})'
|
8
|
+
interpolation: 'Coaster SampleObject interpolation test %{test_this}'
|
8
9
|
TestStandardError:
|
10
|
+
ExampleError:
|
11
|
+
self: 'Test example error'
|
9
12
|
SampleError:
|
13
|
+
self: 'Test sample error'
|
10
14
|
test: 'Test this translation'
|
11
15
|
title: 'Test this title'
|
12
16
|
sample:
|
@@ -48,6 +48,10 @@ module Coaster
|
|
48
48
|
assert_equal 'Coaster SampleObject Title (class.Coaster.Inherited.title)', Inherited._translate(:title)
|
49
49
|
end
|
50
50
|
|
51
|
+
def test_interpolation
|
52
|
+
assert_equal 'Coaster SampleObject interpolation test this interpolated', SampleObject._translate('.interpolation', {test_this: 'this interpolated'}.with_indifferent_access)
|
53
|
+
end
|
54
|
+
|
51
55
|
def teardown
|
52
56
|
I18n.locale = nil
|
53
57
|
I18n.default_locale = nil
|
data/test/test_standard_error.rb
CHANGED
@@ -39,20 +39,16 @@ module Coaster
|
|
39
39
|
raise ExampleError, {wat: 'cha'}
|
40
40
|
end
|
41
41
|
rescue => e
|
42
|
-
assert_equal
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
"http_status"=>500,
|
53
|
-
"message"=>"Test this title"
|
54
|
-
}
|
55
|
-
}, e.to_hash)
|
42
|
+
assert_equal e.to_hash['wat'], 'cha'
|
43
|
+
assert_equal e.to_hash['type'], 'Coaster::TestStandardError::ExampleError'
|
44
|
+
assert_equal e.to_hash['status'], 20
|
45
|
+
assert_equal e.to_hash['http_status'], 500
|
46
|
+
assert_equal e.to_hash['message'], 'Test sample error'
|
47
|
+
assert_equal e.to_hash['cause']['frog'], 'rams'
|
48
|
+
assert_equal e.to_hash['cause']['type'], 'Coaster::TestStandardError::SampleError'
|
49
|
+
assert_equal e.to_hash['cause']['status'], 10
|
50
|
+
assert_equal e.to_hash['cause']['http_status'], 500
|
51
|
+
assert_equal e.to_hash['cause']['message'], 'Test sample error'
|
56
52
|
end
|
57
53
|
|
58
54
|
def test_cause_attributes
|
@@ -62,7 +58,9 @@ module Coaster
|
|
62
58
|
raise ExampleError, {wat: 'cha'}
|
63
59
|
end
|
64
60
|
rescue => e
|
65
|
-
assert_equal
|
61
|
+
assert_equal e.cause.attr['frog'], 'rams'
|
62
|
+
assert_equal e.attr['frog'], 'rams'
|
63
|
+
assert_equal e.attr['wat'], 'cha'
|
66
64
|
end
|
67
65
|
|
68
66
|
def test_to_detail
|
@@ -74,15 +72,15 @@ module Coaster
|
|
74
72
|
rescue => e
|
75
73
|
detail = <<-LOG
|
76
74
|
[Coaster::TestStandardError::ExampleError] status:20
|
77
|
-
MESSAGE: Test
|
75
|
+
MESSAGE: Test sample error
|
78
76
|
@fingerprint: []
|
79
77
|
@tags: {}
|
80
78
|
@level: \"error\"
|
81
|
-
@attributes: {\"wat\"=>\"cha\"}
|
79
|
+
@attributes: {\"frog\"=>\"rams\", \"wat\"=>\"cha\"}
|
82
80
|
@tkey: nil
|
83
81
|
@raven: {}
|
84
82
|
CAUSE: [Coaster::TestStandardError::SampleError] status:10
|
85
|
-
MESSAGE: Test
|
83
|
+
MESSAGE: Test sample error
|
86
84
|
@fingerprint: []
|
87
85
|
@tags: {}
|
88
86
|
@level: \"error\"
|
@@ -108,7 +106,7 @@ LOG
|
|
108
106
|
def test_title_missing
|
109
107
|
raise UntitledError, 'untitled'
|
110
108
|
rescue => e
|
111
|
-
|
109
|
+
assert_nil e.title
|
112
110
|
end
|
113
111
|
|
114
112
|
def root_cause_sample1
|
@@ -138,7 +136,24 @@ LOG
|
|
138
136
|
def test_raven_notes
|
139
137
|
raise SampleError, m: 'foofoo', something: 'other'
|
140
138
|
rescue => e
|
141
|
-
assert_equal e.notes(the_other: 'something')
|
139
|
+
assert_equal e.notes(the_other: 'something')[:extra][:something], 'other'
|
140
|
+
assert_equal e.notes(the_other: 'something')[:extra][:the_other], 'something'
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_to_hash
|
144
|
+
aa # raise NameError
|
145
|
+
rescue => e
|
146
|
+
assert_equal e.to_hash['type'], 'NameError'
|
147
|
+
assert_equal e.to_hash['status'], 999999
|
148
|
+
assert_equal e.to_hash['http_status'], 500
|
149
|
+
assert e.to_hash['message'] =~ /undefined local variable or method `aa'/
|
150
|
+
end
|
151
|
+
|
152
|
+
def test_descriptions
|
153
|
+
raise SampleError
|
154
|
+
rescue => e
|
155
|
+
e.descriptions.merge!(a: 1)
|
156
|
+
assert_equal e.descriptions['a'], 1
|
142
157
|
end
|
143
158
|
end
|
144
159
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: coaster
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- buzz jung
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-07-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: i18n
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
19
|
+
version: '1.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
26
|
+
version: '1.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -226,7 +226,7 @@ signing_key:
|
|
226
226
|
specification_version: 4
|
227
227
|
summary: A little convenient feature for standard library
|
228
228
|
test_files:
|
229
|
-
- test/locales/en.yml
|
230
|
-
- test/test_standard_error.rb
|
231
229
|
- test/test_helper.rb
|
230
|
+
- test/test_standard_error.rb
|
231
|
+
- test/locales/en.yml
|
232
232
|
- test/test_object_translation.rb
|