code_error 0.9.3

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7d3630c871f307f8a79b4c038efac86c2e7f7031
4
+ data.tar.gz: 9c7b3e960adb94896f0d062e5eebffc45bf77ccd
5
+ SHA512:
6
+ metadata.gz: 0ffd780bcf90b43be9c7fa2e6c52ff973623a154ce99edeb1962c25805da98aad659e7969a5461087cd5dc5b84fd3ddae09130308c9b5b9c747a7e26931cc073
7
+ data.tar.gz: 225ab9e1a644db1de28e03d6b3f4518e10a39905f5868d2ab890c174240c18a342f422b8a919b57c754200a67f0f9c44d724212019aac18b4f4942b44cb782e7
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Sibevin Wang
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,331 @@
1
+ # Code Error
2
+
3
+ A code-based customized error.
4
+
5
+ raise MyError.new(10002)
6
+
7
+ ## Why?
8
+
9
+ It is a standard error but it provides more.
10
+
11
+ * All error cases are defined in the same place. Easy to find and reference.
12
+ * Just raising an error with a code, then the corresponding status and message are ready to use.
13
+ * Highly customizable and extendable, you can even re-define the default messages to what you want.
14
+
15
+ ## Usage
16
+
17
+ ### Basic
18
+
19
+ Inherit CodeError::Base to create your own code-based error. You need to implement the "error_codes" method which provides a hash to define your own error code map.
20
+
21
+ class MyError < CodeError::Base
22
+
23
+ private
24
+
25
+ def error_codes
26
+ {
27
+ 20001 => {
28
+ status: :failed,
29
+ msg: 'Purchase information format is incorrect.'
30
+ },
31
+ 20002 => {
32
+ status: :failed,
33
+ msg: 'Device information format is incorrect.'
34
+ },
35
+ 20003 => {
36
+ status: :failed,
37
+ msg: 'Unknown store.'
38
+ },
39
+ 20100 => {
40
+ status: :duplicated,
41
+ msg: 'A duplicated IAP request is sent.'
42
+ },
43
+ 20200 => {
44
+ status: :retry,
45
+ msg: 'Client should send the IAP request again.'
46
+ }
47
+ }
48
+ end
49
+ end
50
+
51
+ Raise an error with a code when you need.
52
+
53
+ raise MyError.new(20001)
54
+
55
+ Rescue and handle it.
56
+
57
+ begin
58
+ #...
59
+ raise MyError.new(20001)
60
+ #...
61
+ rescue MyError => e
62
+ raise e if e.internal?
63
+ msg = e.msg
64
+ code = e.code
65
+ info = e.info
66
+ data = e.data
67
+ case(e.status)
68
+ when :failed
69
+ #...
70
+ when :duplicated
71
+ #...
72
+ else
73
+ #...
74
+ end
75
+ #...
76
+ end
77
+
78
+ ### Customize error code hash
79
+
80
+ A customized code-based error class need to implement the "error_codes" method which provides a hash like:
81
+
82
+ def error_codes
83
+ {
84
+ 20001 => {
85
+ status: :failed,
86
+ msg: 'Purchase information format is incorrect.'
87
+ },
88
+ 20002 => {
89
+ status: :failed,
90
+ msg: 'Device information format is incorrect.'
91
+ },
92
+ 20003 => {
93
+ status: :failed,
94
+ msg: 'Unknown store.'
95
+ },
96
+ 20100 => {
97
+ status: :duplicated,
98
+ msg: 'A duplicated IAP request is sent.',
99
+ masked: true
100
+ },
101
+ 20200 => {
102
+ status: :retry,
103
+ msg: 'Client should send the IAP request again.'
104
+ }
105
+ }
106
+ end
107
+
108
+ where keys are the supported codes and each value is an another hash to store the code information corresponding each codes. The code information hash contains the following keys:
109
+
110
+ * :status - [any type you like] The error status to define the error handling flow. You can get it by calling the "status" method.
111
+ * :msg - [String] The error message. You can get it by calling the "msg" method.
112
+ * :masked - (optional)[Boolean] To define the error message is masked by default or not. The default value is false if no `:masked` is given.
113
+
114
+ ### Raise a code-based error
115
+
116
+ Once you define the error_codes method, raising a code-based error is easy.
117
+
118
+ raise MyError.new(20001)
119
+
120
+ There are three argments in the new method, `MyError.new(code, msg, info)`. If the given code is defined in the error_codes, the error would contain the corresponding status and msg.
121
+
122
+ e = MyError.new(20001)
123
+ e.code # 20001
124
+ e.status # :failed
125
+ e.msg # "Purchase information format is incorrect.(20001)"
126
+
127
+ You can give another string in "msg" arg to overwrite the original message:
128
+
129
+ e = MyError.new(20001, "The another message which would override the original one.")
130
+ e.code # 20001
131
+ e.status # :failed
132
+ e.msg # "The another message which would override the original one.(20001)"
133
+
134
+ If the given code is unknown, the error would become an internal error, i.e., the status is the `:internal` status.
135
+
136
+ e = MyError.new(1111)
137
+ e.code # 1111
138
+ e.status # :internal
139
+ e.msg # "An internal error occurs.(1111)"
140
+ e.internal? # true
141
+
142
+ If a string is given, the error is also an internal error, but the "msg" would keep this string.
143
+
144
+ e = MyError.new("Invalid input!!")
145
+ e.code # 99999
146
+ e.status # :internal
147
+ e.msg # "Invalid input!!"(99999)
148
+ e.internal? # true
149
+
150
+ You can pass anything to the error handling you want through the "info" arg.
151
+
152
+ something = 'what you want...'
153
+ e = MyError.new(20001, nil, something)
154
+ e.info # 'what you want...'
155
+
156
+ There is a special code `:success` which used in the success case.
157
+
158
+ e = MyError.new(:success)
159
+ e.code # 0
160
+ e.status # :success
161
+ e.msg # ""
162
+ e.internal? # false
163
+
164
+ ### Handle the code-base error
165
+
166
+ When you rescue a code-based error, some useful methods are ready to use.
167
+
168
+ * code - The error code
169
+ * status - The error status
170
+ * msg - The error message
171
+ * info - The error information
172
+ * data - A hash contains the values of code, status, msg, info.
173
+ * internal? - To show this error is an internal error or not.
174
+
175
+ Here is an example:
176
+
177
+ e = MyError.new(20001, nil, 'some information')
178
+ e.code # 20001
179
+ e.status # :failed
180
+ e.msg # "Purchase information format is incorrect.(20001)"
181
+ e.info # "some information"
182
+ e.data # { code: 20001, status: :failed, msg: "Purchase information format is incorrect.(20001)", info: 'some information' }
183
+ e.internal? # false
184
+
185
+ ### Configure your code-base error
186
+
187
+ You can override the `config` method in your code-based error to customize the default behavior. Here is an example:
188
+
189
+ class MyError < CodeError::Base
190
+
191
+ private
192
+
193
+ def error_codes
194
+ #...
195
+ end
196
+
197
+ def config
198
+ super.merge({
199
+ success: {
200
+ code: CodeError::SUCCESS_CODE,
201
+ status: CodeError::SUCCESS_STATUS,
202
+ msg: "My own success message."
203
+ },
204
+ internal: {
205
+ code: CodeError::INTERNAL_CODE,
206
+ status: CodeError::INTERNAL_STATUS,
207
+ msg: "My own internal error message."
208
+ },
209
+ masked_msg: "My own masked message",
210
+ append_code_in_msg: :none
211
+ })
212
+ end
213
+ end
214
+
215
+ where the config hash contains the following keys:
216
+
217
+ * :success - Define the success code, status and message.
218
+ * :internal - Define the internal error code, status and message.
219
+ * :masked_msg - [String] Define the message to replace the masked one.
220
+ * :code_in_msg - [:append/:prepend/:none] Define how to embed code in the message. The default option is :append.
221
+
222
+ ### Mask the error message
223
+
224
+ You can mask an error message if you don't want to show it. A masked message would be replaced with the default masked message. There are several ways to do it, they are listed below sorted by the precedence.
225
+
226
+ * Pass `true` to the "masked" arg in the "msg" or "data" method.
227
+
228
+ e = MyError.new(20001)
229
+ e.msg(ture) # "An error occurs.(20001)"
230
+ e.data(true) # { code: 20001, status: :failed, msg: "An error occurs.(20001)", info: {} }
231
+
232
+ * Pass the `:masked` to the "msg" arg in the "new" method.
233
+
234
+ e = MyError.new(20001, :masked)
235
+ e.msg # "An error occurs.(20001)"
236
+
237
+ * Add `masked: true` in the error_codes hash for particular error. Please see [Customize error code hash].
238
+
239
+ The default masked message can be customized to your own message by overwriting the `:masked_msg` in your config hash. Please see [Configure your code-base error].
240
+
241
+ ## I18n
242
+
243
+ We don't support the i18n for simpleness but you can do it yourself. Here is an example:
244
+
245
+ class MyError < CodeError::Base
246
+
247
+ private
248
+
249
+ def error_codes
250
+ {
251
+ 20001 => {
252
+ status: :failed,
253
+ msg: 'code_error.my_error.purchase_info_incorrect'
254
+ },
255
+ 20002 => {
256
+ status: :failed,
257
+ msg: 'code_error.my_error.device_info_incorrect'
258
+ },
259
+ 20003 => {
260
+ status: :failed,
261
+ msg: 'code_error.my_error.unknown_store'
262
+ },
263
+ 20100 => {
264
+ status: :duplicated,
265
+ msg: 'code_error.my_error.duplicated_request'
266
+ },
267
+ 20200 => {
268
+ status: :retry,
269
+ msg: 'code_error.my_error.retry'
270
+ }
271
+ }
272
+ end
273
+
274
+ def config
275
+ super.merge({
276
+ success: {
277
+ code: CodeError::SUCCESS_CODE,
278
+ status: CodeError::SUCCESS_STATUS,
279
+ msg: 'code_error_my_error.success_msg'
280
+ },
281
+ internal: {
282
+ code: CodeError::INTERNAL_CODE,
283
+ status: CodeError::INTERNAL_STATUS,
284
+ msg: 'code_error_my_error.internal_msg'
285
+ },
286
+ masked_msg: 'code_error_my_error.masked_msg',
287
+ append_code_in_msg: :append
288
+ })
289
+ end
290
+ end
291
+
292
+ def show_message(code, msg, masked = false)
293
+ masked = masked || @masked || false
294
+ m = masked ? I18n.t(config[:masked_msg]) : I18n.t(msg)
295
+ code_in_msg = config[:code_in_msg]
296
+ if code != config[:success][:code]
297
+ if code_in_message == :append
298
+ m = I18n.t('code_error.my_error.append_code_msg', msg: m, code: code)
299
+ elsif code_in_message == :prepand
300
+ m = I18n.t('code_error.my_error.prepend_code_msg', msg: m, code: code)
301
+ end
302
+ end
303
+ m
304
+ end
305
+
306
+ And the i18n yml file is:
307
+
308
+ en:
309
+ code_error:
310
+ my_error:
311
+ append_code_msg: "%{msg}(%{code})"
312
+ prepend_code_msg: "(%{code})%{msg}"
313
+ purchase_info_invalid: "Purchase information format is incorrect."
314
+ device_info_invalid: "Device information format is incorrect."
315
+ unknown_store: "Unknown Store."
316
+ duplicated_request: "A duplicated IAP request is sent."
317
+ retry: "Client should send the IAP request again."
318
+
319
+ ## Test
320
+
321
+ Go to code_error gem folder and run
322
+
323
+ ruby ./test/test_all.rb
324
+
325
+ ## Authors
326
+
327
+ Sibevin Wang
328
+
329
+ ## Copyright
330
+
331
+ Copyright (c) 2013 Sibevin Wang. Released under the MIT license.
@@ -0,0 +1,78 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'code_error/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "code_error"
7
+ spec.version = CodeError::VERSION
8
+ spec.authors = ["Sibevin Wang"]
9
+ spec.email = ["sibevin@gmail.com"]
10
+ spec.description = %q{A code-based customized error.}
11
+ spec.summary = <<-EOF
12
+ Inherit CodeError::Base to create your own code-based error. You need to implement the "error_codes" method which provides a hash to define your own error code map.
13
+
14
+ class MyError < CodeError::Base
15
+
16
+ private
17
+
18
+ def error_codes
19
+ {
20
+ 20001 => {
21
+ status: :failed,
22
+ msg: 'Purchase information format is incorrect.'
23
+ },
24
+ 20002 => {
25
+ status: :failed,
26
+ msg: 'Device information format is incorrect.'
27
+ },
28
+ 20003 => {
29
+ status: :failed,
30
+ msg: 'Unknown store.'
31
+ },
32
+ 20100 => {
33
+ status: :duplicated,
34
+ msg: 'A duplicated IAP request is sent.'
35
+ },
36
+ 20200 => {
37
+ status: :retry,
38
+ msg: 'Client should send the IAP request again.'
39
+ }
40
+ }
41
+ end
42
+ end
43
+
44
+ Raise an error with a code when you need.
45
+
46
+ raise MyError.new(20001)
47
+
48
+ Rescue and handle it.
49
+
50
+ begin
51
+ #...
52
+ raise MyError.new(20001)
53
+ #...
54
+ rescue MyError => e
55
+ raise e if e.internal?
56
+ msg = e.msg
57
+ code = e.code
58
+ info = e.info
59
+ data = e.data
60
+ case(e.status)
61
+ when :failed
62
+ #...
63
+ when :duplicated
64
+ #...
65
+ else
66
+ #...
67
+ end
68
+ #...
69
+ end
70
+
71
+ Please see "README" to get more details.
72
+ EOF
73
+ spec.homepage = "https://github.com/sibevin/code_error"
74
+ spec.license = "MIT"
75
+ spec.files = `git ls-files`.split($/)
76
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
77
+ spec.require_paths = ["lib"]
78
+ end
@@ -0,0 +1,75 @@
1
+ module RandomToken
2
+
3
+ # A customized exception for RandomToken
4
+ class RandomTokenError < StandardError
5
+
6
+ # Errors used in RandomToken
7
+ ERRORS = {
8
+ :unknown_seed => {
9
+ :value => 1,
10
+ :msg => "Unknown given seed"
11
+ },
12
+ :not_support_case => {
13
+ :value => 2,
14
+ :msg => "Case feature is not supported in this case, but the case option is given."
15
+ },
16
+ :not_support_friendly => {
17
+ :value => 3,
18
+ :msg => "Friendly feature is not supported in this case, but the friendly option is true."
19
+ },
20
+ :false_friendly_with_given_mask => {
21
+ :value => 4,
22
+ :msg => "The mask is given but the friendly option is false."
23
+ },
24
+ :invalid_strf_pattern => {
25
+ :value => 5,
26
+ :msg => "The given pattern is invalid."
27
+ },
28
+ :invalid_gen_arg => {
29
+ :value => 6,
30
+ :msg => "The given arg is invalid."
31
+ },
32
+ :mask_remove_all_seeds => {
33
+ :value => 7,
34
+ :msg => "The friendly mask removes all seeds."
35
+ },
36
+ :duplicated_option => {
37
+ :value => 8,
38
+ :msg => "The same options are given."
39
+ },
40
+ :invalid_option_value => {
41
+ :value => 9,
42
+ :msg => "The given option value is invalid."
43
+ },
44
+ }
45
+
46
+ attr_reader :code, :value, :msg, :info
47
+
48
+ # The RandomTokenError constructor.
49
+ # @param error [Fixnum, String]
50
+ # You can give a error number defined in the keys of {RandomToken::RandomTokenError::ERRORS} or a string message for internal usage.
51
+ # @param info [Hash]
52
+ # Anything you want to put in the info attribute of RandomTokenError.
53
+ def initialize(error, info = {})
54
+ @code = error
55
+ @info = info
56
+ if ERRORS.keys.include?(error)
57
+ @value = ERRORS[error][:value]
58
+ @msg = ERRORS[error][:msg]
59
+ elsif error.class.name == 'String'
60
+ @code = :internal
61
+ @value = 90000
62
+ @msg = error
63
+ else
64
+ @code = :internal
65
+ @value = 99999
66
+ @msg = "Internal Error"
67
+ end
68
+ end
69
+
70
+ # Override the message method to show more information in RandomTokenError
71
+ def message
72
+ "RandomTokenError(#{@code.to_s}): value = #{@value}, msg = #{@msg}, info = #{@info.inspect}"
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,3 @@
1
+ module CodeError
2
+ VERSION = '0.9.3'
3
+ end
data/lib/code_error.rb ADDED
@@ -0,0 +1,102 @@
1
+ module CodeError
2
+
3
+ SUCCESS_CODE = 0
4
+ SUCCESS_STATUS = :success
5
+ SUCCESS_MSG = ''
6
+
7
+ INTERNAL_CODE = 99999
8
+ INTERNAL_STATUS = :internal
9
+ INTERNAL_MSG = 'An internal error occurs.'
10
+
11
+ MASKED_MSG = 'An error occurs.'
12
+
13
+ class Base < StandardError
14
+ attr_reader :code, :status, :info
15
+
16
+ def initialize(code = nil, msg = nil, info = {})
17
+ @code = code
18
+ @info = info
19
+ if error_codes.keys.include?(code)
20
+ @status = error_codes[code][:status]
21
+ @msg = error_codes[code][:msg]
22
+ @masked = error_codes[code][:masked] || false
23
+ if msg == :masked
24
+ @masked = true
25
+ elsif msg.is_a?(String)
26
+ @masked = false
27
+ @msg = msg
28
+ end
29
+ elsif code == config[:success][:code]
30
+ @code = config[:success][:code]
31
+ @status = config[:success][:status]
32
+ @msg = config[:success][:msg]
33
+ else
34
+ # unknown code
35
+ @status = config[:internal][:status]
36
+ if code.is_a?(String)
37
+ @code = config[:internal][:code]
38
+ @msg = code
39
+ else
40
+ @code = code || config[:internal][:code]
41
+ @msg = msg || config[:internal][:msg]
42
+ end
43
+ end
44
+ end
45
+
46
+ def message
47
+ self.data.inspect
48
+ end
49
+
50
+ def data(masked = nil)
51
+ msg = show_message(@code, @msg, masked)
52
+ { status: @status, code: @code, msg: msg, info: @info }
53
+ end
54
+
55
+ def msg(masked = nil)
56
+ show_message(@code, @msg, masked)
57
+ end
58
+
59
+ def internal?
60
+ @status == config[:internal][:status]
61
+ end
62
+
63
+ private
64
+
65
+ def error_codes
66
+ raise 'You should implement error_codes method in your code-based class.'
67
+ end
68
+
69
+ def config
70
+ {
71
+ :success => {
72
+ :code => SUCCESS_CODE,
73
+ :status => SUCCESS_STATUS,
74
+ :msg => SUCCESS_MSG
75
+ },
76
+ :internal => {
77
+ :code => INTERNAL_CODE,
78
+ :status => INTERNAL_STATUS,
79
+ :msg => INTERNAL_MSG
80
+ },
81
+ :masked_msg => MASKED_MSG,
82
+ :code_in_msg => :append
83
+ }
84
+ end
85
+
86
+ def show_message(code, msg, masked = nil)
87
+ if masked == nil
88
+ masked = @masked || false
89
+ end
90
+ m = masked ? config[:masked_msg] : msg
91
+ code_in_msg = config[:code_in_msg]
92
+ if code != config[:success][:code]
93
+ if code_in_msg == :append
94
+ m = "#{m}(#{code})"
95
+ elsif code_in_msg == :prepand
96
+ m = "(#{code})#{m}"
97
+ end
98
+ end
99
+ m
100
+ end
101
+ end
102
+ end
data/test/test_all.rb ADDED
@@ -0,0 +1,9 @@
1
+ require "test/unit"
2
+
3
+ $LOAD_PATH.unshift("#{File.dirname(__FILE__)}")
4
+ require "test_helper"
5
+ require "code_error"
6
+ require "test_new"
7
+ require "test_config"
8
+ require "test_masked"
9
+ require "test_code_in_msg"
@@ -0,0 +1,85 @@
1
+ require "test/unit"
2
+
3
+ $LOAD_PATH.unshift("#{File.dirname(__FILE__)}")
4
+ require "test_helper"
5
+ require "code_error"
6
+
7
+ class TestCodeInMsg < Test::Unit::TestCase
8
+
9
+ ERROR_CODE_1 = 1
10
+ ERROR_MSG_1 = 'The error message for code 1.'
11
+ ERROR_STATUS_1 = :failed
12
+
13
+ class AppendError < CodeError::Base
14
+ def error_codes
15
+ {
16
+ ERROR_CODE_1 => {
17
+ status: ERROR_STATUS_1,
18
+ msg: ERROR_MSG_1,
19
+ }
20
+ }
21
+ end
22
+
23
+ def config
24
+ super.merge({
25
+ :code_in_msg => :append
26
+ })
27
+ end
28
+ end
29
+
30
+ class PrependError < CodeError::Base
31
+ def error_codes
32
+ {
33
+ ERROR_CODE_1 => {
34
+ status: ERROR_STATUS_1,
35
+ msg: ERROR_MSG_1,
36
+ }
37
+ }
38
+ end
39
+
40
+ def config
41
+ super.merge({
42
+ :code_in_msg => :prepand
43
+ })
44
+ end
45
+ end
46
+
47
+ class NoneError < CodeError::Base
48
+ def error_codes
49
+ {
50
+ ERROR_CODE_1 => {
51
+ status: ERROR_STATUS_1,
52
+ msg: ERROR_MSG_1,
53
+ }
54
+ }
55
+ end
56
+
57
+ def config
58
+ super.merge({
59
+ :code_in_msg => :none
60
+ })
61
+ end
62
+ end
63
+
64
+ def test_code_in_msg_should_return_a_message_with_the_code_appended_after_it_if_append_config_is_given
65
+ e = AppendError.new(ERROR_CODE_1)
66
+ assert(e.msg == "#{ERROR_MSG_1}(#{ERROR_CODE_1})")
67
+ end
68
+
69
+ def test_code_in_msg_should_return_a_message_with_the_code_prepended_before_it_if_prepend_config_is_given
70
+ e = PrependError.new(ERROR_CODE_1)
71
+ assert(e.msg == "(#{ERROR_CODE_1})#{ERROR_MSG_1}")
72
+ end
73
+
74
+ def test_code_in_msg_should_return_a_message_without_the_code_if_none_config_is_given
75
+ e = NoneError.new(ERROR_CODE_1)
76
+ assert(e.msg == "#{ERROR_MSG_1}")
77
+ end
78
+
79
+ def test_code_in_msg_should_return_a_message_without_the_code_if_it_is_a_success_error
80
+ e = AppendError.new(CodeError::SUCCESS_CODE)
81
+ assert(e.msg == "#{CodeError::SUCCESS_MSG}")
82
+ e = PrependError.new(CodeError::SUCCESS_CODE)
83
+ assert(e.msg == "#{CodeError::SUCCESS_MSG}")
84
+ end
85
+ end
@@ -0,0 +1,116 @@
1
+ require "test/unit"
2
+
3
+ $LOAD_PATH.unshift("#{File.dirname(__FILE__)}")
4
+ require "test_helper"
5
+ require "code_error"
6
+
7
+ class TestConfig < Test::Unit::TestCase
8
+
9
+ ERROR_CODE_1 = 1
10
+ ERROR_MSG_1 = 'The error message for code 1.'
11
+ ERROR_STATUS_1 = :failed
12
+
13
+ ERROR_CODE_2 = 2
14
+ ERROR_MSG_2 = 'The error message for code 2.'
15
+ ERROR_STATUS_2 = :failed
16
+
17
+ ERROR_CODE_UNDEFINED = 55688
18
+
19
+ MY_SUCCESS_CODE = :my_success_code
20
+ MY_SUCCESS_MSG = 'My success error message.'
21
+ MY_SUCCESS_STATUS = :my_success_status
22
+
23
+ MY_INTERNAL_CODE = :my_internal_code
24
+ MY_INTERNAL_MSG = 'My internal error message.'
25
+ MY_INTERNAL_STATUS = :my_internal_status
26
+
27
+ MY_MASKED_MSG = 'My masked message.'
28
+
29
+ class ConfigError < CodeError::Base
30
+ def error_codes
31
+ {
32
+ ERROR_CODE_1 => {
33
+ status: ERROR_STATUS_1,
34
+ msg: ERROR_MSG_1,
35
+ },
36
+ ERROR_CODE_2 => {
37
+ :status => ERROR_STATUS_2,
38
+ :msg => ERROR_MSG_2,
39
+ :masked => true
40
+ }
41
+ }
42
+ end
43
+
44
+ def config
45
+ {
46
+ :success => {
47
+ :code => MY_SUCCESS_CODE,
48
+ :msg => MY_SUCCESS_MSG,
49
+ :status => MY_SUCCESS_STATUS
50
+ },
51
+ :internal => {
52
+ :code => MY_INTERNAL_CODE,
53
+ :msg => MY_INTERNAL_MSG,
54
+ :status => MY_INTERNAL_STATUS
55
+ },
56
+ :masked_msg => MY_MASKED_MSG,
57
+ :code_in_msg => :append
58
+ }
59
+ end
60
+ end
61
+
62
+ def test_config_should_return_the_correspond_data_if_given_code_is_defined
63
+ e = ConfigError.new(ERROR_CODE_1)
64
+ assert(e.code == ERROR_CODE_1)
65
+ assert(e.status == ERROR_STATUS_1)
66
+ assert(e.msg == "#{ERROR_MSG_1}(#{ERROR_CODE_1})")
67
+ assert(!e.internal?)
68
+ end
69
+
70
+ def test_config_should_return_an_internal_error_with_given_code_if_given_code_is_undefined
71
+ e = ConfigError.new(ERROR_CODE_UNDEFINED)
72
+ assert(e.code == ERROR_CODE_UNDEFINED)
73
+ assert(e.status == MY_INTERNAL_STATUS)
74
+ assert(e.msg == "#{MY_INTERNAL_MSG}(#{ERROR_CODE_UNDEFINED})")
75
+ assert(e.internal?)
76
+ end
77
+
78
+ def test_config_should_return_an_internal_error_with_given_msg_if_given_code_is_a_string
79
+ msg = 'An error message.'
80
+ e = ConfigError.new(msg)
81
+ assert(e.code == MY_INTERNAL_CODE)
82
+ assert(e.status == MY_INTERNAL_STATUS)
83
+ assert(e.msg == "#{msg}(#{MY_INTERNAL_CODE})")
84
+ assert(e.internal?)
85
+ end
86
+
87
+ def test_config_should_return_an_success_error_if_given_code_is_a_success_code
88
+ e = ConfigError.new(MY_SUCCESS_CODE)
89
+ assert(e.code == MY_SUCCESS_CODE)
90
+ assert(e.status == MY_SUCCESS_STATUS)
91
+ assert(e.msg == "#{MY_SUCCESS_MSG}")
92
+ assert(!e.internal?)
93
+ end
94
+
95
+ def test_config_should_mask_the_msg_if_given_msg_is_masked
96
+ e = ConfigError.new(ERROR_CODE_1, :masked)
97
+ assert(e.code == ERROR_CODE_1)
98
+ assert(e.status == ERROR_STATUS_1)
99
+ assert(e.msg == "#{MY_MASKED_MSG}(#{ERROR_CODE_1})")
100
+ assert(!e.internal?)
101
+ end
102
+
103
+ def test_config_should_mask_the_msg_by_default_if_true_masked_config_is_given
104
+ e = ConfigError.new(ERROR_CODE_2)
105
+ assert(e.code == ERROR_CODE_2)
106
+ assert(e.status == ERROR_STATUS_2)
107
+ assert(e.msg == "#{MY_MASKED_MSG}(#{ERROR_CODE_2})")
108
+ assert(!e.internal?)
109
+ end
110
+
111
+ def test_config_should_contain_the_info_if_an_info_is_given
112
+ info = 'some information'
113
+ e = ConfigError.new(ERROR_CODE_1, nil, info)
114
+ assert(e.info == info)
115
+ end
116
+ end
@@ -0,0 +1 @@
1
+ $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../lib")
@@ -0,0 +1,89 @@
1
+ require "test/unit"
2
+
3
+ $LOAD_PATH.unshift("#{File.dirname(__FILE__)}")
4
+ require "test_helper"
5
+ require "code_error"
6
+
7
+ class TestMasked < Test::Unit::TestCase
8
+
9
+ ERROR_CODE_1 = 1
10
+ ERROR_MSG_1 = 'The error message for code 1.'
11
+ ERROR_STATUS_1 = :failed
12
+
13
+ ERROR_CODE_2 = 2
14
+ ERROR_MSG_2 = 'The error message for code 2.'
15
+ ERROR_STATUS_2 = :failed
16
+
17
+ ERROR_CODE_UNDEFINED = 55688
18
+
19
+ class MaskedError < CodeError::Base
20
+ def error_codes
21
+ {
22
+ ERROR_CODE_1 => {
23
+ :status => ERROR_STATUS_1,
24
+ :msg => ERROR_MSG_1,
25
+ },
26
+ ERROR_CODE_2 => {
27
+ :status => ERROR_STATUS_2,
28
+ :msg => ERROR_MSG_2,
29
+ :masked => true
30
+ }
31
+ }
32
+ end
33
+ end
34
+
35
+ def test_masked_should_mask_the_message_if_the_true_masked_arg_is_given_in_msg_and_data
36
+ e = MaskedError.new(ERROR_CODE_1)
37
+ assert(e.msg(true) == "#{CodeError::MASKED_MSG}(#{ERROR_CODE_1})")
38
+ assert(e.data(true) == { :code => ERROR_CODE_1,
39
+ :status => ERROR_STATUS_1,
40
+ :msg => "#{CodeError::MASKED_MSG}(#{ERROR_CODE_1})",
41
+ :info => {} })
42
+ end
43
+
44
+ def test_masked_should_mask_the_message_if_given_code_is_undefined_but_the_true_masked_arg_is_given_in_msg_and_data
45
+ e = MaskedError.new(ERROR_CODE_UNDEFINED)
46
+ assert(e.msg(true) == "#{CodeError::MASKED_MSG}(#{ERROR_CODE_UNDEFINED})")
47
+ assert(e.data(true) == { :code => ERROR_CODE_UNDEFINED,
48
+ :status => CodeError::INTERNAL_STATUS,
49
+ :msg => "#{CodeError::MASKED_MSG}(#{ERROR_CODE_UNDEFINED})",
50
+ :info => {} })
51
+ end
52
+
53
+ def test_masked_should_mask_the_message_if_given_code_is_a_string_but_the_true_masked_arg_is_given_in_msg_and_data
54
+ msg = 'An error message.'
55
+ e = MaskedError.new(msg)
56
+ assert(e.msg(true) == "#{CodeError::MASKED_MSG}(#{CodeError::INTERNAL_CODE})")
57
+ assert(e.data(true) == { :code => CodeError::INTERNAL_CODE,
58
+ :status => CodeError::INTERNAL_STATUS,
59
+ :msg => "#{CodeError::MASKED_MSG}(#{CodeError::INTERNAL_CODE})",
60
+ :info => {} })
61
+ end
62
+
63
+ def test_masked_should_mask_the_message_if_given_code_is_a_success_code_but_the_true_masked_arg_is_given_in_msg_and_data
64
+ e = MaskedError.new(CodeError::SUCCESS_CODE)
65
+ assert(e.msg(true) == "#{CodeError::MASKED_MSG}")
66
+ assert(e.data(true) == { :code => CodeError::SUCCESS_CODE,
67
+ :status => CodeError::SUCCESS_STATUS,
68
+ :msg => "#{CodeError::MASKED_MSG}",
69
+ :info => {} })
70
+ end
71
+
72
+ def test_masked_should_unmask_the_message_if_given_msg_is_masked_in_new_but_the_false_masked_arg_is_given_in_msg_and_data
73
+ e = MaskedError.new(ERROR_CODE_1, :masked)
74
+ assert(e.msg(false) == "#{ERROR_MSG_1}(#{ERROR_CODE_1})")
75
+ assert(e.data(false) == { :code => ERROR_CODE_1,
76
+ :status => ERROR_STATUS_1,
77
+ :msg => "#{ERROR_MSG_1}(#{ERROR_CODE_1})",
78
+ :info => {} })
79
+ end
80
+
81
+ def test_masked_should_unmask_the_message_if_true_masked_config_is_given_but_the_false_masked_arg_is_given_in_msg_and_data
82
+ e = MaskedError.new(ERROR_CODE_2)
83
+ assert(e.msg(false) == "#{ERROR_MSG_2}(#{ERROR_CODE_2})")
84
+ assert(e.data(false) == { :code => ERROR_CODE_2,
85
+ :status => ERROR_STATUS_2,
86
+ :msg => "#{ERROR_MSG_2}(#{ERROR_CODE_2})",
87
+ :info => {} })
88
+ end
89
+ end
data/test/test_new.rb ADDED
@@ -0,0 +1,100 @@
1
+ require "test/unit"
2
+
3
+ $LOAD_PATH.unshift("#{File.dirname(__FILE__)}")
4
+ require "test_helper"
5
+ require "code_error"
6
+
7
+ class TestNew < Test::Unit::TestCase
8
+
9
+ class InvalidError < CodeError::Base; end;
10
+
11
+ ERROR_CODE_1 = 1
12
+ ERROR_MSG_1 = 'The error message for code 1.'
13
+ ERROR_STATUS_1 = :failed
14
+
15
+ ERROR_CODE_2 = 2
16
+ ERROR_MSG_2 = 'The error message for code 2.'
17
+ ERROR_STATUS_2 = :failed
18
+
19
+ ERROR_CODE_UNDEFINED = 55688
20
+
21
+ class TestError < CodeError::Base
22
+ def error_codes
23
+ {
24
+ ERROR_CODE_1 => {
25
+ :status => ERROR_STATUS_1,
26
+ :msg => ERROR_MSG_1,
27
+ },
28
+ ERROR_CODE_2 => {
29
+ :status => ERROR_STATUS_2,
30
+ :msg => ERROR_MSG_2,
31
+ :masked => true
32
+ }
33
+ }
34
+ end
35
+ end
36
+
37
+ def test_new_should_raise_an_exception_if_the_error_codes_is_undefined
38
+ assert_raise(RuntimeError) { InvalidError.new }
39
+ end
40
+
41
+ def test_new_should_return_the_correspond_data_if_given_code_is_defined
42
+ e = TestError.new(ERROR_CODE_1)
43
+ assert(e.code == ERROR_CODE_1)
44
+ assert(e.status == ERROR_STATUS_1)
45
+ assert(e.msg == "#{ERROR_MSG_1}(#{ERROR_CODE_1})")
46
+ assert(e.data == { :code => ERROR_CODE_1,
47
+ :status => ERROR_STATUS_1,
48
+ :msg => "#{ERROR_MSG_1}(#{ERROR_CODE_1})",
49
+ :info => {} })
50
+ assert(e.message == e.data.inspect)
51
+ assert(!e.internal?)
52
+ end
53
+
54
+ def test_new_should_return_an_internal_error_with_given_code_if_given_code_is_undefined
55
+ e = TestError.new(ERROR_CODE_UNDEFINED)
56
+ assert(e.code == ERROR_CODE_UNDEFINED)
57
+ assert(e.status == CodeError::INTERNAL_STATUS)
58
+ assert(e.msg == "#{CodeError::INTERNAL_MSG}(#{ERROR_CODE_UNDEFINED})")
59
+ assert(e.internal?)
60
+ end
61
+
62
+ def test_new_should_return_an_internal_error_with_given_msg_if_given_code_is_a_string
63
+ msg = 'An error message.'
64
+ e = TestError.new(msg)
65
+ assert(e.code == CodeError::INTERNAL_CODE)
66
+ assert(e.status == CodeError::INTERNAL_STATUS)
67
+ assert(e.msg == "#{msg}(#{CodeError::INTERNAL_CODE})")
68
+ assert(e.internal?)
69
+ end
70
+
71
+ def test_new_should_return_an_success_error_if_given_code_is_a_success_code
72
+ e = TestError.new(CodeError::SUCCESS_CODE)
73
+ assert(e.code == CodeError::SUCCESS_CODE)
74
+ assert(e.status == CodeError::SUCCESS_STATUS)
75
+ assert(e.msg == "#{CodeError::SUCCESS_MSG}")
76
+ assert(!e.internal?)
77
+ end
78
+
79
+ def test_new_should_mask_the_msg_if_given_msg_is_masked
80
+ e = TestError.new(ERROR_CODE_1, :masked)
81
+ assert(e.code == ERROR_CODE_1)
82
+ assert(e.status == ERROR_STATUS_1)
83
+ assert(e.msg == "#{CodeError::MASKED_MSG}(#{ERROR_CODE_1})")
84
+ assert(!e.internal?)
85
+ end
86
+
87
+ def test_new_should_mask_the_msg_by_default_if_true_masked_config_is_given
88
+ e = TestError.new(ERROR_CODE_2)
89
+ assert(e.code == ERROR_CODE_2)
90
+ assert(e.status == ERROR_STATUS_2)
91
+ assert(e.msg == "#{CodeError::MASKED_MSG}(#{ERROR_CODE_2})")
92
+ assert(!e.internal?)
93
+ end
94
+
95
+ def test_new_should_contain_the_info_if_an_info_is_given
96
+ info = 'some information'
97
+ e = TestError.new(ERROR_CODE_1, nil, info)
98
+ assert(e.info == info)
99
+ end
100
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: code_error
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.3
5
+ platform: ruby
6
+ authors:
7
+ - Sibevin Wang
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-09-17 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A code-based customized error.
14
+ email:
15
+ - sibevin@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - LICENSE.txt
21
+ - README.md
22
+ - code_error.gemspec
23
+ - lib/code_error.rb
24
+ - lib/code_error/random_token_error.rb
25
+ - lib/code_error/version.rb
26
+ - test/test_all.rb
27
+ - test/test_code_in_msg.rb
28
+ - test/test_config.rb
29
+ - test/test_helper.rb
30
+ - test/test_masked.rb
31
+ - test/test_new.rb
32
+ homepage: https://github.com/sibevin/code_error
33
+ licenses:
34
+ - MIT
35
+ metadata: {}
36
+ post_install_message:
37
+ rdoc_options: []
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ requirements: []
51
+ rubyforge_project:
52
+ rubygems_version: 2.0.6
53
+ signing_key:
54
+ specification_version: 4
55
+ summary: 'Inherit CodeError::Base to create your own code-based error. You need to
56
+ implement the "error_codes" method which provides a hash to define your own error
57
+ code map. class MyError < CodeError::Base private def error_codes { 20001 =>
58
+ { status: :failed, msg: ''Purchase information format is incorrect.'' }, 20002 =>
59
+ { status: :failed, msg: ''Device information format is incorrect.'' }, 20003 =>
60
+ { status: :failed, msg: ''Unknown store.'' }, 20100 => { status: :duplicated, msg:
61
+ ''A duplicated IAP request is sent.'' }, 20200 => { status: :retry, msg: ''Client
62
+ should send the IAP request again.'' } } end end Raise an error with a code when
63
+ you need. raise MyError.new(20001) Rescue and handle it. begin #... raise MyError.new(20001)
64
+ #... rescue MyError => e raise e if e.internal? msg = e.msg code = e.code info =
65
+ e.info data = e.data case(e.status) when :failed #... when :duplicated #... else
66
+ #... end #... end Please see "README" to get more details.'
67
+ test_files:
68
+ - test/test_all.rb
69
+ - test/test_code_in_msg.rb
70
+ - test/test_config.rb
71
+ - test/test_helper.rb
72
+ - test/test_masked.rb
73
+ - test/test_new.rb
74
+ has_rdoc: