code_error 0.9.3 → 1.0.0

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.
data/code_error.gemspec CHANGED
@@ -9,47 +9,44 @@ Gem::Specification.new do |spec|
9
9
  spec.email = ["sibevin@gmail.com"]
10
10
  spec.description = %q{A code-based customized error.}
11
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.
12
+ Inherit CodeError::Base to create your own code-based error. You need to assign "error_codes" with a hash to define your own error code map.
13
13
 
14
14
  class MyError < CodeError::Base
15
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
- }
16
+ error_codes({
17
+ purchase_info_incorrect: {
18
+ status: :failed,
19
+ msg: 'Purchase information format is incorrect.'
20
+ },
21
+ device_info_incorrect: {
22
+ status: :failed,
23
+ msg: 'Device information format is incorrect.'
24
+ },
25
+ unknown_store: {
26
+ status: :failed,
27
+ msg: 'Unknown store.'
28
+ },
29
+ duplicated_request: {
30
+ status: :duplicated,
31
+ msg: 'A duplicated IAP request is sent.'
32
+ },
33
+ resend_iap: {
34
+ status: :retry,
35
+ msg: 'Client should send the IAP request again.'
40
36
  }
41
- end
37
+ })
38
+
42
39
  end
43
40
 
44
41
  Raise an error with a code when you need.
45
42
 
46
- raise MyError.new(20001)
43
+ raise MyError.gen(:purchase_info_incorrect)
47
44
 
48
45
  Rescue and handle it.
49
46
 
50
47
  begin
51
48
  #...
52
- raise MyError.new(20001)
49
+ raise MyError.gen(:purchase_info_incorrect)
53
50
  #...
54
51
  rescue MyError => e
55
52
  raise e if e.internal?
@@ -75,4 +72,5 @@ Please see "README" to get more details.
75
72
  spec.files = `git ls-files`.split($/)
76
73
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
77
74
  spec.require_paths = ["lib"]
75
+ spec.add_development_dependency 'minitest', '~> 5.0'
78
76
  end
data/lib/code_error.rb CHANGED
@@ -1,102 +1,161 @@
1
1
  module CodeError
2
2
 
3
- SUCCESS_CODE = 0
3
+ SUCCESS_CODE = :success
4
4
  SUCCESS_STATUS = :success
5
5
  SUCCESS_MSG = ''
6
6
 
7
- INTERNAL_CODE = 99999
7
+ INTERNAL_CODE = :internal
8
8
  INTERNAL_STATUS = :internal
9
9
  INTERNAL_MSG = 'An internal error occurs.'
10
10
 
11
- MASKED_MSG = 'An error occurs.'
11
+ DEFAULT_MASKED_MSG = 'An error occurs.'
12
+
13
+ DEFAULT_POS = :none
14
+
15
+ DEFAULT_MASKED = false
12
16
 
13
17
  class Base < StandardError
14
18
  attr_reader :code, :status, :info
15
19
 
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
20
+ @@global_config = {
21
+ :success => {
22
+ :code => SUCCESS_CODE,
23
+ :status => SUCCESS_STATUS,
24
+ :msg => SUCCESS_MSG,
25
+ :pos => DEFAULT_POS,
26
+ :masked => DEFAULT_MASKED
27
+ },
28
+ :internal => {
29
+ :code => INTERNAL_CODE,
30
+ :status => INTERNAL_STATUS,
31
+ :msg => INTERNAL_MSG,
32
+ :pos => DEFAULT_POS,
33
+ :masked => DEFAULT_MASKED
34
+ },
35
+ :masked_msg => DEFAULT_MASKED_MSG,
36
+ :pos => DEFAULT_POS,
37
+ :masked => DEFAULT_MASKED
38
+ }
39
+
40
+ def self.gen(code = nil, options = {})
41
+ merge_klass_config
42
+ @error_codes = {} unless @error_codes
43
+ new(code, options, @error_codes, @klass_config)
44
44
  end
45
45
 
46
- def message
47
- self.data.inspect
46
+ def self.error_codes(data = {})
47
+ @error_codes = data
48
48
  end
49
49
 
50
- def data(masked = nil)
51
- msg = show_message(@code, @msg, masked)
52
- { status: @status, code: @code, msg: msg, info: @info }
50
+ def self.success(data = {})
51
+ merge_klass_config( :success => data )
53
52
  end
54
53
 
55
- def msg(masked = nil)
56
- show_message(@code, @msg, masked)
54
+ def self.internal(data = {})
55
+ merge_klass_config( :internal => data )
57
56
  end
58
57
 
59
- def internal?
60
- @status == config[:internal][:status]
58
+ def self.masked_msg(msg = nil)
59
+ merge_klass_config( :masked_msg => msg )
61
60
  end
62
61
 
63
- private
62
+ def self.masked(masked = false)
63
+ merge_klass_config( :masked => masked )
64
+ end
65
+
66
+ def self.pos(pos = nil)
67
+ merge_klass_config( :pos => pos )
68
+ end
64
69
 
65
- def error_codes
66
- raise 'You should implement error_codes method in your code-based class.'
70
+ def message
71
+ self.data.inspect
67
72
  end
68
73
 
69
- def config
74
+ def data(options = {})
70
75
  {
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
76
+ :status => @status,
77
+ :code => @code,
78
+ :msg => show_message(@code, @msg, options),
79
+ :info => @info
83
80
  }
84
81
  end
85
82
 
86
- def show_message(code, msg, masked = nil)
87
- if masked == nil
88
- masked = @masked || false
83
+ def msg(options = {})
84
+ show_message(@code, @msg, options)
85
+ end
86
+
87
+ def internal?
88
+ @status == @internal_status
89
+ end
90
+
91
+ # === private methods ===
92
+
93
+ def self.merge_klass_config(new_option = {})
94
+ unless @klass_config
95
+ @klass_config = {
96
+ :success => {},
97
+ :internal => {},
98
+ :masked_msg => nil,
99
+ :pos => nil,
100
+ :masked => nil
101
+ }
89
102
  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}"
103
+ @klass_config.merge!(new_option)
104
+ end
105
+
106
+ private_class_method :merge_klass_config
107
+
108
+ def initialize(code = nil, options = {}, code_map = {}, klass_config = {})
109
+ @code = code
110
+ @info = options[:info]
111
+ @masked_msg = options[:masked_msg] || klass_config[:masked_msg] || @@global_config[:masked_msg]
112
+ @success_code = klass_config[:success][:code] || @@global_config[:success][:code]
113
+ @internal_code = klass_config[:internal][:code] || @@global_config[:internal][:code]
114
+ @internal_status = klass_config[:internal][:status] || @@global_config[:internal][:status]
115
+ if code_map.keys.include?(code)
116
+ @status = code_map[code][:status]
117
+ @msg = options[:msg] || code_map[code][:msg] || klass_config[:internal][:msg] || @@global_config[:internal][:msg]
118
+ @pos = nil_next(options[:pos], nil_next(code_map[code][:pos], nil_next(klass_config[:pos], @@global_config[:pos])))
119
+ @masked = nil_next(options[:masked], nil_next(code_map[code][:masked], nil_next(klass_config[:masked], @@global_config[:masked])))
120
+ elsif code == @success_code
121
+ @code = @success_code
122
+ @status = options[:status] || klass_config[:success][:status] || @@global_config[:success][:status]
123
+ @msg = options[:msg] || klass_config[:success][:msg] || @@global_config[:success][:msg]
124
+ @pos = options[:pos] || klass_config[:success][:pos] || @@global_config[:success][:pos]
125
+ @masked = nil_next(options[:masked], nil_next(klass_config[:success][:masked], @@global_config[:success][:masked]))
126
+ else
127
+ # :internal or unknown code
128
+ if code.is_a?(String)
129
+ @code = @internal_code
130
+ @msg = code
131
+ else
132
+ @code = code
133
+ @msg = options[:msg] || klass_config[:internal][:msg] || @@global_config[:internal][:msg]
97
134
  end
135
+ @status = options[:status] || @internal_status
136
+ @pos = options[:pos] || klass_config[:internal][:pos] || @@global_config[:internal][:pos]
137
+ @masked = nil_next(options[:masked], nil_next(klass_config[:internal][:masked], @@global_config[:internal][:masked]))
138
+ end
139
+ end
140
+
141
+ private_class_method :new
142
+
143
+ private
144
+
145
+ def show_message(code, msg, options = {})
146
+ masked = nil_next(options[:masked], @masked)
147
+ pos = nil_next(options[:pos], @pos)
148
+ display_msg = masked ? @masked_msg : msg
149
+ case pos
150
+ when :append then "#{display_msg} (#{code})"
151
+ when :prepend then "(#{code}) #{display_msg}"
152
+ else
153
+ "#{display_msg}"
98
154
  end
99
- m
155
+ end
156
+
157
+ def nil_next(first, second)
158
+ (first.nil? ? second : first)
100
159
  end
101
160
  end
102
161
  end
@@ -1,3 +1,3 @@
1
1
  module CodeError
2
- VERSION = '0.9.3'
2
+ VERSION = '1.0.0'
3
3
  end
data/test/test_all.rb CHANGED
@@ -1,9 +1,9 @@
1
- require "test/unit"
1
+ require 'minitest/autorun'
2
2
 
3
3
  $LOAD_PATH.unshift("#{File.dirname(__FILE__)}")
4
4
  require "test_helper"
5
5
  require "code_error"
6
- require "test_new"
7
- require "test_config"
6
+ require "test_gen"
8
7
  require "test_masked"
9
- require "test_code_in_msg"
8
+ require "test_pos"
9
+ require "test_config"
data/test/test_config.rb CHANGED
@@ -1,116 +1,103 @@
1
- require "test/unit"
1
+ require "minitest/autorun"
2
2
 
3
3
  $LOAD_PATH.unshift("#{File.dirname(__FILE__)}")
4
4
  require "test_helper"
5
5
  require "code_error"
6
6
 
7
- class TestConfig < Test::Unit::TestCase
7
+ class TestConfig < Minitest::Test
8
8
 
9
- ERROR_CODE_1 = 1
10
- ERROR_MSG_1 = 'The error message for code 1.'
11
- ERROR_STATUS_1 = :failed
9
+ CONFIG_ERROR_CODE_1 = :config_code1
10
+ CONFIG_ERROR_MSG_1 = 'The config error message for code 1.'
11
+ CONFIG_ERROR_STATUS_1 = :config_failed
12
12
 
13
- ERROR_CODE_2 = 2
14
- ERROR_MSG_2 = 'The error message for code 2.'
15
- ERROR_STATUS_2 = :failed
13
+ CONFIG_ERROR_CODE_2 = :config_code2
14
+ CONFIG_ERROR_MSG_2 = 'The config error message for code 2.'
15
+ CONFIG_ERROR_STATUS_2 = :config_failed
16
16
 
17
- ERROR_CODE_UNDEFINED = 55688
17
+ CONFIG_ERROR_CODE_UNDEFINED = :config_undefined_code
18
18
 
19
- MY_SUCCESS_CODE = :my_success_code
20
- MY_SUCCESS_MSG = 'My success error message.'
21
- MY_SUCCESS_STATUS = :my_success_status
19
+ MY_SUCCESS_CODE = :my_config_success_code
20
+ MY_SUCCESS_MSG = 'My config success error message.'
21
+ MY_SUCCESS_STATUS = :my_config_success_status
22
22
 
23
- MY_INTERNAL_CODE = :my_internal_code
24
- MY_INTERNAL_MSG = 'My internal error message.'
25
- MY_INTERNAL_STATUS = :my_internal_status
23
+ MY_INTERNAL_CODE = :my_config_internal_code
24
+ MY_INTERNAL_MSG = 'My config internal error message.'
25
+ MY_INTERNAL_STATUS = :my_config_internal_status
26
26
 
27
- MY_MASKED_MSG = 'My masked message.'
27
+ MY_MASKED_MSG = 'My config masked message.'
28
28
 
29
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
- }
30
+ error_codes({
31
+ CONFIG_ERROR_CODE_1 => {
32
+ :status => CONFIG_ERROR_STATUS_1,
33
+ :msg => CONFIG_ERROR_MSG_1,
34
+ },
35
+ CONFIG_ERROR_CODE_2 => {
36
+ :status => CONFIG_ERROR_STATUS_2,
37
+ :msg => CONFIG_ERROR_MSG_2,
38
+ :masked => true
41
39
  }
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
40
+ })
41
+
42
+ success({
43
+ :code => MY_SUCCESS_CODE,
44
+ :msg => MY_SUCCESS_MSG,
45
+ :status => MY_SUCCESS_STATUS
46
+ })
47
+
48
+ internal({
49
+ :code => MY_INTERNAL_CODE,
50
+ :msg => MY_INTERNAL_MSG,
51
+ :status => MY_INTERNAL_STATUS
52
+ })
53
+
54
+ masked_msg MY_MASKED_MSG
60
55
  end
61
56
 
62
57
  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})")
58
+ e = ConfigError.gen(CONFIG_ERROR_CODE_1)
59
+ assert(e.code == CONFIG_ERROR_CODE_1)
60
+ assert(e.status == CONFIG_ERROR_STATUS_1)
61
+ assert(e.msg == CONFIG_ERROR_MSG_1)
67
62
  assert(!e.internal?)
68
63
  end
69
64
 
70
65
  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)
66
+ e = ConfigError.gen(CONFIG_ERROR_CODE_UNDEFINED)
67
+ assert(e.code == CONFIG_ERROR_CODE_UNDEFINED)
73
68
  assert(e.status == MY_INTERNAL_STATUS)
74
- assert(e.msg == "#{MY_INTERNAL_MSG}(#{ERROR_CODE_UNDEFINED})")
69
+ assert(e.msg == MY_INTERNAL_MSG)
75
70
  assert(e.internal?)
76
71
  end
77
72
 
78
73
  def test_config_should_return_an_internal_error_with_given_msg_if_given_code_is_a_string
79
74
  msg = 'An error message.'
80
- e = ConfigError.new(msg)
75
+ e = ConfigError.gen(msg)
81
76
  assert(e.code == MY_INTERNAL_CODE)
82
77
  assert(e.status == MY_INTERNAL_STATUS)
83
- assert(e.msg == "#{msg}(#{MY_INTERNAL_CODE})")
78
+ assert(e.msg == msg)
84
79
  assert(e.internal?)
85
80
  end
86
81
 
87
82
  def test_config_should_return_an_success_error_if_given_code_is_a_success_code
88
- e = ConfigError.new(MY_SUCCESS_CODE)
83
+ e = ConfigError.gen(MY_SUCCESS_CODE)
89
84
  assert(e.code == MY_SUCCESS_CODE)
90
85
  assert(e.status == MY_SUCCESS_STATUS)
91
- assert(e.msg == "#{MY_SUCCESS_MSG}")
86
+ assert(e.msg == MY_SUCCESS_MSG)
92
87
  assert(!e.internal?)
93
88
  end
94
89
 
95
90
  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})")
91
+ e = ConfigError.gen(CONFIG_ERROR_CODE_1, :masked => true)
92
+ assert(e.code == CONFIG_ERROR_CODE_1)
93
+ assert(e.status == CONFIG_ERROR_STATUS_1)
94
+ assert(e.msg == MY_MASKED_MSG)
108
95
  assert(!e.internal?)
109
96
  end
110
97
 
111
98
  def test_config_should_contain_the_info_if_an_info_is_given
112
99
  info = 'some information'
113
- e = ConfigError.new(ERROR_CODE_1, nil, info)
100
+ e = ConfigError.gen(CONFIG_ERROR_CODE_1, :info => info)
114
101
  assert(e.info == info)
115
102
  end
116
103
  end