vexapion 0.3.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.
@@ -0,0 +1,482 @@
1
+ # coding: utf-8
2
+
3
+ require 'vexapion'
4
+
5
+ module Vexapion
6
+
7
+ # coincheckのAPIラッパークラスです。
8
+ # 各メソッドの戻り値は下記URLを参照してください。
9
+ # @see https://coincheck.com/ja/documents/exchange/api
10
+
11
+ class Coincheck < BaseExchanges
12
+
13
+ def initialize(key = nil, secret = nil)
14
+ super(key, secret)
15
+
16
+ @public_url = "https://coincheck.com/api/"
17
+ @private_url = "https://coincheck.com/api/"
18
+ set_verify_mode(OpenSSL::SSL::VERIFY_NONE)
19
+ end
20
+
21
+ # Public API
22
+
23
+ # @raise RequestFailed APIリクエストの失敗
24
+ # @raise SocketError ソケットエラー
25
+ # @raise RetryException リクエストの結果が確認できないとき 408, 500, 503
26
+ # @raise Warning 何かがおかしい時(200 && response.body==nil), 509
27
+ # @raise Error クライアントエラー 400, 401, 403
28
+ # @raise Fatal APIラッパーの修正が必要と思われるエラー, 404
29
+
30
+ # ティッカー
31
+ # @return [Hash]
32
+ def ticker
33
+ public_get('ticker')
34
+ end
35
+
36
+ # 取引履歴
37
+ # @return [Array]
38
+ def trades
39
+ public_get('trades')
40
+ end
41
+
42
+ # 板情報
43
+ # @return [Hash]
44
+ def order_books
45
+ public_get('order_books')
46
+ end
47
+
48
+ # レート取得
49
+ # @param [String] pair 必須 現在は'btc_jpy'のみ
50
+ # @param [String] order_type 必須 'sell' or 'buy'
51
+ # @param [Integer] price 省略可 注文での金額 例28000
52
+ # @param [Float] amount 省略可 注文での量 例0.1
53
+ # @return [Hash]
54
+ def rate(pair, order_type, price='', amount='')
55
+ params = {
56
+ 'pair' => pair.downcase,
57
+ 'order_type' => order_type,
58
+ }
59
+ params['price'] = price if price != ''
60
+ params['amount'] = amount if amount != ''
61
+
62
+ public_get('exchange/orders/rate')
63
+ end
64
+
65
+ # 販売所レート取得
66
+ # @param [String] pair ('btc_jpy', 'eth_jpy', 'zec_btc' ...etc)
67
+ # @return [Hash]
68
+ def sales_rate(pair, price='', amount='')
69
+ params = {
70
+ 'pair' => pair.downcase,
71
+ }
72
+
73
+ public_get('exchange/orders/rate', params)
74
+ end
75
+
76
+ # Private API
77
+
78
+ #長くなって訳わからなくなるので、order_typeごとに分割
79
+ # 注文: buy/sell => order
80
+ # 成行注文: market_buy/market_sell => market_order
81
+ # レバレッジ注文: leverage_buy/leverage_sell => order_leverage
82
+ # レバレッジ成行注文: leverage_buy/leverage_sell => market_order_leverage
83
+ # レバレッジ注文クローズ: close_short/close_long => close_position
84
+ # レバレッジ注文成行クローズ: close_short/close_long =>
85
+ # close_position_market_order
86
+
87
+ # orders APIがややこしいので、一般的なものに置き換え
88
+ # order_typeに buy / sell を指定する
89
+
90
+
91
+ # @param [String] pair 現在は'btc_jpy'のみ
92
+ # @param [String] order_type 'sell' or 'buy'
93
+ # @param [Integer] rate 注文での金額 例28000
94
+ # @param [Float] amount 注文での量 例0.1
95
+ # @param [Integer] stop_loss_rate 省略可 逆指値レート
96
+ # @return [Hash]
97
+ def order(pair, order_type, rate, amount, stop_loss_rate = '')
98
+ params = {
99
+ 'rate' => rate,
100
+ 'amount' => amount,
101
+ 'pair' => pair.downcase,
102
+ 'order_type' => order_type.downcase
103
+ }
104
+ params['stop_loss_rate'] = stop_loss_rate if stop_loss_rate != ''
105
+
106
+ post('exchange/orders', params)
107
+ end
108
+
109
+ #成行注文
110
+ #buyの時はamountにJPYの数量を指定する(amount_jpy円分買うという指定方法)
111
+ # @param [String] pair 現在は'btc_jpy'のみ
112
+ # @param [Float] amount_jpy 注文での量 例5000
113
+ # @param [Integer] stop_loss_rate 省略可 逆指値レート
114
+ # @return [Hash]
115
+ def market_buy(pair, amount_jpy, stop_loss_rate = '')
116
+ params = {
117
+ 'pair' => pair.downcase,
118
+ 'order_type' => "market_buy",
119
+ 'market_buy_amount' => amount_jpy
120
+ }
121
+ params['stop_loss_rate'] = stop_loss_rate if stop_loss_rate != ''
122
+
123
+ post('exchange/orders', params)
124
+ end
125
+
126
+ #成行注文
127
+ #sellの時はamountにBTCの数量を指定する
128
+ # @param [String] pair 現在は'btc_jpy'のみ
129
+ # @param [Float] amount 注文での量 例0.1
130
+ # @param [Integer] stop_loss_rate 省略可 逆指値レート
131
+ # @return [Hash]
132
+ def market_sell(pair, amount, stop_loss_rate = '')
133
+ params = {
134
+ 'pair' => pair.downcase,
135
+ 'order_type' => "market_sell",
136
+ 'amount' => amount
137
+ }
138
+ params['stop_loss_rate'] = stop_loss_rate if stop_loss_rate != ''
139
+
140
+ post('exchange/orders', params)
141
+ end
142
+
143
+
144
+ #レバレッジ新規取引
145
+ # @param [String] pair 現在は'btc_jpy'のみ
146
+ # @param [String] order_type 'sell' or 'buy'
147
+ # @param [Integer] rate 注文のレート 例28000
148
+ # @param [Float] amount 注文での量 例0.1
149
+ # @param [Integer] stop_loss_rate 省略可 逆指値レート
150
+ # @return [Hash]
151
+ def order_leverage(pair, order_type, rate, amount, stop_loss_rate = '')
152
+ params = {
153
+ 'pair' => pair.downcase,
154
+ 'rate' => rate.to_f,
155
+ 'amount' => amount.to_f,
156
+ 'order_type' => "leverage_#{order_type.downcase}"
157
+ }
158
+ params['stop_loss_rate'] = stop_loss_rate if stop_loss_rate != ''
159
+
160
+ post('exchange/orders', params)
161
+ end
162
+
163
+ #レバレッジ新規取引(成行)
164
+ # @param [String] pair 現在は'btc_jpy'のみ
165
+ # @param [String] order_type 'sell' or 'buy'
166
+ # @param [Float] amount 注文での量 例0.1
167
+ # @param [Integer] stop_loss_rate 省略可 逆指値レート
168
+ # @return [Hash]
169
+ def market_order_leverage(pair, order_type, amount, stop_loss_rate = '')
170
+ params = {
171
+ 'pair' => pair.downcase,
172
+ 'amount' => amount.to_f,
173
+ 'order_type' => "leverage_#{order_type.downcase}"
174
+ }
175
+ params['stop_loss_rate'] = stop_loss_rate if stop_loss_rate != ''
176
+
177
+ post('exchange/orders', params)
178
+ end
179
+
180
+ #レバレッジ決済売買
181
+ # @param [String] pair 現在は'btc_jpy'のみ
182
+ # @param [String] close_position 'long' or 'short'
183
+ # @param [Integer] position_id ポジションID
184
+ # @param [Integer] rate 注文のレート 例28000
185
+ # @param [Float] amount 注文での量 例0.1
186
+ # @return [Hash]
187
+ def close_position(pair, close_position, position_id, rate, amount)
188
+ params = {
189
+ 'pair' => pair.downcase,
190
+ 'order_type' => "close_#{close_position.downcase}",
191
+ 'position_id' => position_id.to_i,
192
+ 'rate' => rate.to_f,
193
+ 'amount' => amount.to_f
194
+ }
195
+
196
+ post('exchange/orders', params)
197
+ end
198
+
199
+ #レバレッジ決済取引(成行)
200
+ # @param [String] pair 現在は'btc_jpy'のみ
201
+ # @param [String] close_position 'long' or 'short'
202
+ # @param [Integer] position_id ポジションID
203
+ # @param [Float] amount 注文での量 例0.1
204
+ # @return [Hash]
205
+ def close_position_market_order(pair, close_position, position_id, amount)
206
+ params = {
207
+ 'pair' => pair.downcase,
208
+ 'order_type' => "close_#{close_position.downcase}",
209
+ 'position_id' => position_id.to_i,
210
+ 'amount' => amount.to_f
211
+ }
212
+
213
+ post('exchange/orders', params)
214
+ end
215
+
216
+ alias close_position_without_limit close_position_market_order
217
+
218
+ # 未約定の注文一覧
219
+ # @return [Hash]
220
+ def opens
221
+ get('exchange/orders/opens')
222
+ end
223
+
224
+ # 注文のキャンセル
225
+ # @param [Integer] id キャンセルしたい注文ID
226
+ # @return [Hash]
227
+ def cancel(id)
228
+ delete("exchange/orders/#{id}")
229
+ end
230
+
231
+ # 約定履歴
232
+ # @return [Hash]
233
+ def transactions
234
+ get('exchange/orders/transactions')
235
+ end
236
+
237
+ # 約定履歴(ページネーション)
238
+ # @return [Hash]
239
+ def transactions
240
+ get('exchange/orders/transactions_pagination')
241
+ end
242
+
243
+ # ポジション一覧
244
+ # @param [String] status 省略可 'open'/'closed'を指定出来ます
245
+ # @return [Hash]
246
+ def position(status='')
247
+ params = Hash.new
248
+ params['status'] = status if status != ''
249
+ get('exchange/leverage/positions', params)
250
+ end
251
+
252
+ # 残高
253
+ # @return [Hash]
254
+ def balance
255
+ get('accounts/balance')
256
+ end
257
+
258
+ # レバレッジアカウントの残高
259
+ # @return [Hash]
260
+ def leverage_balance
261
+ get('accounts/leverage_balance')
262
+ end
263
+
264
+ # ビットコインの送金
265
+ # @param [String] address 送り先のビットコインアドレス
266
+ # @param [Float] amount 送りたいビットコインの量
267
+ # @return [Hash]
268
+ def send_money(address, amount)
269
+ post('send_money', 'address' => address, 'amount' => amount)
270
+ end
271
+
272
+ # ビットコイン送金履歴
273
+ # @param [String] currency 現在はBTCのみ対応。省略時のデフォルトはBTC
274
+ # @return [Hash]
275
+ def send_history(currency = 'BTC')
276
+ get('send_money', 'currency' => currency)
277
+ end
278
+
279
+ # ビットコイン受取履歴
280
+ # @param [String] currency 現在はBTCのみ対応。省略時のデフォルトはBTC
281
+ # @return [Hash]
282
+ def deposit_history(currency = 'BTC')
283
+ get('deposit_money', 'currency' => currency)
284
+ end
285
+
286
+ # ビットコインの高速入金
287
+ # @param [Integer] id 高速入金させたいビットコイン受取履歴のID
288
+ # @return [Hash]
289
+ def deposit_accelerate(id)
290
+ post("deposit_money/#{id}/fast")
291
+ end
292
+
293
+ # アカウント情報
294
+ # @return [Hash]
295
+ def accounts
296
+ get('accounts')
297
+ end
298
+
299
+
300
+ # Private API (JPY BANK)
301
+
302
+ # 銀行口座一覧
303
+ # @return [Hash]
304
+ def bank_accounts
305
+ get('bank_accounts')
306
+ end
307
+
308
+ # 銀行口座の登録
309
+ # @param [String] bank 銀行名
310
+ # @param [String] branch 支店名
311
+ # @param [String] type 口座の種類 (普通口座 futsu / 当座預金口座 toza)
312
+ # @param [String] number_str 口座番号 例:'0123456'
313
+ # @param [String] name 口座名義
314
+ # @return [Hash]
315
+ def regist_bank_account(bank, branch, type, number_str, name)
316
+ params = {
317
+ 'bank_name' => bank,
318
+ 'branch_name' => branch,
319
+ 'bank_account_type' => type,
320
+ 'number' => number_str,
321
+ 'name' => name
322
+ }
323
+
324
+ post('bank_accounts', params)
325
+ end
326
+
327
+ # 銀行口座の削除
328
+ # @param [Integer] id 銀行口座一覧のID
329
+ # @return [Hash]
330
+ def delete_bank_account(id)
331
+ delete("bank_accounts/#{id}")
332
+ end
333
+
334
+ # 日本円出金履歴
335
+ # @return [Hash]
336
+ def bank_withdraw_history
337
+ get('withdraws')
338
+ end
339
+
340
+ # 日本円出金申請
341
+ # @param [Integer] id 銀行口座一覧のID
342
+ # @param [Integer] amount 金額
343
+ # @param [String] currency 通貨名 現在はJPYのみ。省略時デフォルト'JPY'
344
+ # @param [Boolean] is_fast 高速出金オプション 省略時デフォルトはfalse
345
+ # @return [Hash]
346
+ def bank_withdraw(id, amount, currency = 'JPY', is_fast = false)
347
+ params = {
348
+ 'bank_account_id' => id,
349
+ 'amount' => amount,
350
+ 'currency' => currency,
351
+ 'is_fast' => is_fast
352
+ }
353
+
354
+ post('withdraws', params)
355
+ end
356
+
357
+ # 日本円出金申請のキャンセル
358
+ # @param [Integer] id 出金申請のID
359
+ # @return [Hash]
360
+ def cancel_bank_withdraw(id)
361
+ delete("withdraws/#{id}")
362
+ end
363
+
364
+ # 信用取引
365
+
366
+ # 借入申請
367
+ # @param [String] currency 借りたい通貨
368
+ # @param [Float] amount 借りたい量
369
+ # @return [Hash]
370
+ def borrow(currency, amount)
371
+ params = { 'amount' => amount, 'currency' => currency }
372
+
373
+ post('lending/borrows', params)
374
+ end
375
+
376
+ # 借入中一覧
377
+ # @return [Hash]
378
+ def borrow_list
379
+ get('lending/borrows/matches')
380
+ end
381
+
382
+ # 返済
383
+ # @param [Integer] id 借入中一覧のID
384
+ # @return [Hash]
385
+ def repayment(id)
386
+ post("lending/borrows/#{id}/repay")
387
+ end
388
+
389
+ # transfers (レバレッジアカウントへ振替)
390
+
391
+ # レバレッジアカウントへ振替
392
+ # @param [String] currency 通貨 現在はJPYのみ
393
+ # @param [Float] amount 移動する数量
394
+ # @return [Hash]
395
+ def to_leverage(currency, amount)
396
+ params = { 'currency' => currency, 'amount' => amount }
397
+
398
+ post('exchange/transfers/to_leverage', params)
399
+ end
400
+
401
+ # レバレッジアカウントから振替
402
+ # @param [String] currency 通貨 現在はJPYのみ
403
+ # @param [Float] amount 移動する数量
404
+ # @return [Hash]
405
+ def from_leverage(currency, amount)
406
+ params = { 'currency' => currency, 'amount' => amount }
407
+
408
+ post('exchange/transfers/from_leverage', params)
409
+ end
410
+
411
+ # Create request header & body
412
+
413
+ private
414
+
415
+ def public_get(method)
416
+ uri = URI.parse "#{@public_url}#{method}"
417
+ request = Net::HTTP::Get.new(uri.request_uri)
418
+
419
+ do_command(uri, request)
420
+ end
421
+
422
+ def get(method, params = '')
423
+ nonce = get_nonce.to_s
424
+ uri = URI.parse "#{@private_url}#{method}"
425
+ params = params.to_json if params != '' #URI.encode_www_form(params)
426
+
427
+ message = "#{nonce}#{uri.to_s}#{params}"
428
+ sig = signature(message)
429
+ headers = header(nonce, sig)
430
+ request = Net::HTTP::Get.new(uri.request_uri, headers)
431
+ request.body = params
432
+
433
+ res = do_command(uri, request)
434
+ error_check(res) #TODO check require
435
+ res
436
+ end
437
+
438
+ def post(method, params = '')
439
+ nonce = get_nonce.to_s
440
+ uri = URI.parse "#{@private_url}#{method}"
441
+ params = params.to_json #URI.encode_www_form(params)
442
+
443
+ message = "#{nonce}#{uri.to_s}#{params}"
444
+ sig = signature(message)
445
+ headers = header(nonce, sig)
446
+ request = Net::HTTP::Post.new(uri.request_uri, initheader = headers)
447
+ request.body = params if params != ''
448
+
449
+ res = do_command(uri, request)
450
+ error_check(res) #check ok
451
+ res
452
+ end
453
+
454
+ def delete(method)
455
+ nonce = get_nonce.to_s
456
+ uri = URI.parse "#{@private_url}#{method}"
457
+ message = nonce + uri.to_s
458
+ sig = signature(message)
459
+ headers = header(nonce, sig)
460
+ request = Net::HTTP::Delete.new(uri.request_uri, headers)
461
+
462
+ res = do_command(uri, request)
463
+ error_check(res) #TODO check require
464
+ res
465
+ end
466
+
467
+ def signature(message)
468
+ algo = OpenSSL::Digest.new('sha256')
469
+ OpenSSL::HMAC.hexdigest(algo, @secret, message)
470
+ end
471
+
472
+ def header(nonce, signature)
473
+ {
474
+ 'Content-Type' => "application/json",
475
+ 'ACCESS-KEY' => @key,
476
+ 'ACCESS-NONCE' => nonce,
477
+ 'ACCESS-SIGNATURE' => signature
478
+ }
479
+ end
480
+
481
+ end #of class
482
+ end #of VirturalCurrencyExchanger module
@@ -0,0 +1,167 @@
1
+ # coding: utf-8
2
+
3
+ require 'vexapion'
4
+
5
+ module Vexapion
6
+
7
+ class HTTPClient
8
+
9
+ attr_writer :timeout, :timeout_keepalive, :min_interval, :num_of_retry
10
+
11
+ def initialize(i_sec=0.5, i_num=1)
12
+ @connections = {}
13
+ @timeout = 10
14
+ #以前のリクエストで使ったコネクションの再利用を許可する秒数
15
+ @timeout_keepalive = 300
16
+ @sleep_in_sec = i_sec
17
+ @min_interval = i_sec
18
+ @num_of_retry = i_num
19
+ @last_access_time = Time.now.to_f
20
+ end
21
+
22
+ def terminate
23
+ @connections.values.each do |connection|
24
+ connection.finish
25
+ end
26
+ end
27
+
28
+ def connection(uri, verify_mode)
29
+ key = uri.host + uri.port.to_s + (uri.scheme == 'https').to_s
30
+ if @connections[key].nil? || @connections[key].started?
31
+ @connections[key] = build_http(uri, verify_mode)
32
+ end
33
+ @connections[key]
34
+ end
35
+
36
+ def build_http(uri, vmode)
37
+ http = Net::HTTP.new(uri.host, uri.port, nil, nil)
38
+ #http.set_debug_output($stderr)
39
+ http.use_ssl = (uri.scheme == 'https')
40
+ http.verify_mode = vmode #if (uri.scheme == 'https') && !vmode.nil?
41
+ #p "set verify_mode #{vmode}" #if (uri.scheme == 'https') && !@vmode.nil?
42
+ http.open_timeout = @timeout
43
+ http.read_timeout = @timeout
44
+ http.keep_alive_timeout = @timeout_keepalive
45
+
46
+ http.start
47
+ http
48
+ end
49
+
50
+ # HTTPのリクエスト
51
+ # @param [String] uri uri
52
+ # @param [String] request request
53
+ # @param [Integer] verify_mode OpenSSL::SSL::VERIFY_*を指定する
54
+ # @raise SocketError ソケットエラー
55
+ # @raise RetryException リクエストが成功したか確認できない時 408, 500, 503
56
+ # @raise Warning 何かおかしい時 (200&&response.body==nil), 509
57
+ # @raise Error クライアントのエラー 400, 401, 403, 404
58
+ # @raise Fatal APIラッパーの修正が必要になると思われるエラー
59
+ # @return [String] request.bodyを返す
60
+ def http_request(uri, request, verify_mode=nil)
61
+ prev_wait = retry_wait = @sleep_in_sec
62
+ @num_of_retry.times do
63
+ #最低接続間隔の保証
64
+ now = Time.now.to_f
65
+ elapse = now - @last_access_time
66
+ if elapse < @min_interval
67
+ s = @min_interval - elapse
68
+ sleep s
69
+ end
70
+ @last_access_time = Time.now.to_f
71
+ #puts (@last_access_time - now + elapse).round(4)*1000
72
+
73
+ begin
74
+ #t1 = Time.now.to_f
75
+ http = connection(uri, verify_mode)
76
+ response = http.request(request)
77
+ #t2 = Time.now.to_f
78
+ #STDERR.puts "\nAPIcall: response: #{(t2-t1).round(4)*1000}ms"
79
+ rescue SocketError => e
80
+ fail SocketError.new(success, e.body, e)
81
+ #raise
82
+ end
83
+
84
+ case response
85
+
86
+ #1.success
87
+ when Net::HTTPSuccess
88
+ #2.success but response.body == ''
89
+ #if response.body == ''
90
+ # puts warning message
91
+ #t = Time.now.strftime("%d %H:%M:%S.%3N")
92
+ #str = "[response is void]\nurl=%s\nstatus=%d: %s\n"%[
93
+ # uri.to_s, response.code, response.message]
94
+ #STDERR.puts "#{t} #{str}"
95
+ #end
96
+
97
+ return response.body
98
+
99
+ #3.server error
100
+ when Net::ReadTimeout, Net::HTTPServerError
101
+ # retryするつもりだったけど、アプリに任せる
102
+ #retry_wait = wait_fb(prev_wait, retry_wait)
103
+ handle_api_error(response)
104
+ #raise
105
+
106
+ #4.client error
107
+ when Net::HTTPClientError
108
+ # raise exception
109
+ #print_error_message(uri, response.message)
110
+ #raise Vexapion::HTTPClientException
111
+ handle_api_error(response)
112
+ #raise
113
+
114
+ #5. other
115
+ else
116
+ fail Fatal.new(http_status_code, message)
117
+ #raise
118
+ end #of case
119
+
120
+ end #of retry
121
+ # error
122
+ raise VexapionServerError
123
+ end #of response
124
+
125
+ def wait_fb(prev_wait, retry_wait)
126
+ sleep retry_wait
127
+ retry_wait + prev_wait
128
+ end
129
+
130
+ def handle_api_error(response)
131
+ http_status_code = response.code.to_i
132
+ message = "#{response.message} #{response.body}"
133
+
134
+ puts "http_status #{http_status_code}"
135
+
136
+ case http_status_code
137
+ when 400
138
+ fail InvalidRequestError.new(http_status_code, message)
139
+
140
+ when 401
141
+ fail AuthenticationError.new(http_status_code, message)
142
+
143
+ when 403
144
+ fail ForbiddenError.new(http_status_code, message)
145
+
146
+ when 404
147
+ fail NotFoundError.new(http_status_code, message)
148
+
149
+ when 408
150
+ fail RequestTimeout.new(http_status_code, message)
151
+
152
+ when 500
153
+ fail ServiceUnavailableError.new(http_status_code, message)
154
+
155
+ when 509
156
+ fail LimitExceededError.new(http_status_code, message)
157
+
158
+ else
159
+ #puts "http_client.rb: Error: #{http_status_code} #{message}"
160
+ fail Fatal.new(http_status_code, message)
161
+
162
+ end #of case
163
+ end #of handle_api_error
164
+
165
+ end #of class
166
+
167
+ end #of module Vexapion
@@ -0,0 +1,74 @@
1
+ # coding: utf-8
2
+
3
+ # based off of quandl gem: https://github.com/quandl/quandl-ruby
4
+
5
+ module Vexapion
6
+
7
+ class HTTPError < StandardError
8
+ attr_reader :http_status_code
9
+ attr_reader :message
10
+
11
+ def initialize(code = nil, msg = nil)
12
+ @http_status_code = code
13
+ @message = msg
14
+ end
15
+
16
+ def to_s
17
+ "#{@http_status_code}: #{@message}"
18
+ end
19
+ end
20
+
21
+ #apiラッパー側でリトライさせたいエラー
22
+ class RetryException < HTTPError
23
+ end
24
+
25
+ #場合によってはアプリ側で無視できるエラー
26
+ class Warning < HTTPError
27
+ end
28
+
29
+ #アプリ側で止めて書き直しが必要なエラー
30
+ class Error < HTTPError
31
+ end
32
+
33
+ #ラッパーの書き直しが必要なエラー
34
+ class Fatal < HTTPError
35
+ end
36
+
37
+
38
+ #408 Request Timeout
39
+ class RequestTimeout < RetryException
40
+ end
41
+
42
+ #500
43
+ class InternalServerError < RetryException
44
+ end
45
+
46
+ #503
47
+ class ServiceUnavailableError < RetryException
48
+ end
49
+
50
+ #Request Success but response.body == nil
51
+ class ResponseDataError < Warning
52
+ end
53
+
54
+ #509, and API Limit?
55
+ class LimitExceededError < Warning
56
+ end
57
+
58
+ #400
59
+ class InvalidRequestError < Error
60
+ end
61
+
62
+ #401
63
+ class AuthenticationError < Error
64
+ end
65
+
66
+ #403
67
+ class ForbiddenError < Error
68
+ end
69
+
70
+ #404
71
+ class NotFoundError < Error
72
+ end
73
+
74
+ end #of Vexapion module