taps2 0.5.5 → 0.6.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.
- checksums.yaml +4 -4
- data/{README.rdoc → README.md} +29 -22
- data/bin/{schema → schema2} +17 -8
- data/bin/{schema.cmd → schema2.cmd} +0 -0
- data/bin/{taps → taps2} +1 -1
- data/lib/taps/chunksize.rb +16 -12
- data/lib/taps/cli.rb +33 -38
- data/lib/taps/config.rb +2 -2
- data/lib/taps/data_stream.rb +256 -262
- data/lib/taps/errors.rb +1 -1
- data/lib/taps/log.rb +1 -1
- data/lib/taps/monkey.rb +10 -9
- data/lib/taps/multipart.rb +1 -2
- data/lib/taps/operation.rb +81 -86
- data/lib/taps/progress_bar.rb +42 -45
- data/lib/taps/schema.rb +2 -2
- data/lib/taps/server.rb +37 -38
- data/lib/taps/utils.rb +31 -34
- data/lib/taps/version.rb +13 -13
- data/lib/vendor/okjson.rb +115 -161
- data/spec/base.rb +2 -2
- data/spec/chunksize_spec.rb +6 -6
- data/spec/cli_spec.rb +6 -6
- data/spec/data_stream_spec.rb +4 -4
- data/spec/operation_spec.rb +17 -18
- data/spec/server_spec.rb +7 -7
- data/spec/utils_spec.rb +20 -20
- metadata +38 -39
- data/VERSION.yml +0 -5
data/lib/taps/progress_bar.rb
CHANGED
@@ -10,14 +10,14 @@
|
|
10
10
|
#
|
11
11
|
|
12
12
|
class ProgressBar
|
13
|
-
VERSION =
|
13
|
+
VERSION = '0.9'.freeze
|
14
14
|
|
15
|
-
def initialize
|
15
|
+
def initialize(title, total, out = STDERR)
|
16
16
|
@title = title
|
17
17
|
@total = total
|
18
18
|
@out = out
|
19
19
|
@terminal_width = 80
|
20
|
-
@bar_mark =
|
20
|
+
@bar_mark = '='
|
21
21
|
@current = 0
|
22
22
|
@previous = 0
|
23
23
|
@finished_p = false
|
@@ -25,7 +25,7 @@ class ProgressBar
|
|
25
25
|
@previous_time = @start_time
|
26
26
|
@title_width = 14
|
27
27
|
@format = "%-#{@title_width}s %3d%% %s %s"
|
28
|
-
@format_arguments = [
|
28
|
+
@format_arguments = %i[title percentage bar stat]
|
29
29
|
clear
|
30
30
|
show
|
31
31
|
end
|
@@ -35,11 +35,12 @@ class ProgressBar
|
|
35
35
|
attr_accessor :start_time
|
36
36
|
|
37
37
|
private
|
38
|
+
|
38
39
|
def fmt_bar
|
39
40
|
bar_width = do_percentage * @terminal_width / 100
|
40
|
-
|
41
|
-
|
42
|
-
|
41
|
+
format('|%s%s|',
|
42
|
+
@bar_mark * bar_width,
|
43
|
+
' ' * (@terminal_width - bar_width))
|
43
44
|
end
|
44
45
|
|
45
46
|
def fmt_percentage
|
@@ -47,68 +48,68 @@ class ProgressBar
|
|
47
48
|
end
|
48
49
|
|
49
50
|
def fmt_stat
|
50
|
-
|
51
|
+
@finished_p ? elapsed : eta
|
51
52
|
end
|
52
53
|
|
53
54
|
def fmt_stat_for_file_transfer
|
54
|
-
if @finished_p
|
55
|
-
|
55
|
+
if @finished_p
|
56
|
+
format('%s %s %s', bytes, transfer_rate, elapsed)
|
56
57
|
else
|
57
|
-
|
58
|
+
format('%s %s %s', bytes, transfer_rate, eta)
|
58
59
|
end
|
59
60
|
end
|
60
61
|
|
61
62
|
def fmt_title
|
62
|
-
@title[0,(@title_width - 1)] +
|
63
|
+
@title[0, (@title_width - 1)] + ':'
|
63
64
|
end
|
64
65
|
|
65
|
-
def convert_bytes
|
66
|
+
def convert_bytes(bytes)
|
66
67
|
if bytes < 1024
|
67
|
-
|
68
|
+
format('%6dB', bytes)
|
68
69
|
elsif bytes < 1024 * 1000 # 1000kb
|
69
|
-
|
70
|
-
elsif bytes < 1024 * 1024 * 1000
|
71
|
-
|
70
|
+
format('%5.1fKB', bytes.to_f / 1024)
|
71
|
+
elsif bytes < 1024 * 1024 * 1000 # 1000mb
|
72
|
+
format('%5.1fMB', bytes.to_f / 1024 / 1024)
|
72
73
|
else
|
73
|
-
|
74
|
+
format('%5.1fGB', bytes.to_f / 1024 / 1024 / 1024)
|
74
75
|
end
|
75
76
|
end
|
76
77
|
|
77
78
|
def transfer_rate
|
78
79
|
bytes_per_second = @current.to_f / (Time.now - @start_time)
|
79
|
-
|
80
|
+
format('%s/s', convert_bytes(bytes_per_second))
|
80
81
|
end
|
81
82
|
|
82
83
|
def bytes
|
83
84
|
convert_bytes(@current)
|
84
85
|
end
|
85
86
|
|
86
|
-
def format_time
|
87
|
+
def format_time(t)
|
87
88
|
t = t.to_i
|
88
89
|
sec = t % 60
|
89
90
|
min = (t / 60) % 60
|
90
91
|
hour = t / 3600
|
91
|
-
|
92
|
+
format('%02d:%02d:%02d', hour, min, sec)
|
92
93
|
end
|
93
94
|
|
94
95
|
# ETA stands for Estimated Time of Arrival.
|
95
96
|
def eta
|
96
97
|
if @current == 0
|
97
|
-
|
98
|
+
'ETA: --:--:--'
|
98
99
|
else
|
99
100
|
elapsed = Time.now - @start_time
|
100
|
-
eta = elapsed * @total / @current - elapsed
|
101
|
-
|
101
|
+
eta = elapsed * @total / @current - elapsed
|
102
|
+
format('ETA: %s', format_time(eta))
|
102
103
|
end
|
103
104
|
end
|
104
105
|
|
105
106
|
def elapsed
|
106
107
|
elapsed = Time.now - @start_time
|
107
|
-
|
108
|
+
format('Time: %s', format_time(elapsed))
|
108
109
|
end
|
109
110
|
|
110
111
|
def eol
|
111
|
-
|
112
|
+
@finished_p ? "\n" : "\r"
|
112
113
|
end
|
113
114
|
|
114
115
|
def do_percentage
|
@@ -124,10 +125,10 @@ class ProgressBar
|
|
124
125
|
default_width = 80
|
125
126
|
begin
|
126
127
|
tiocgwinsz = 0x5413
|
127
|
-
data = [0, 0, 0, 0].pack(
|
128
|
-
if @out.ioctl(tiocgwinsz, data) >= 0
|
129
|
-
_, cols = data.unpack(
|
130
|
-
|
128
|
+
data = [0, 0, 0, 0].pack('SSSS')
|
129
|
+
if @out.ioctl(tiocgwinsz, data) >= 0
|
130
|
+
_, cols = data.unpack('SSSS')
|
131
|
+
cols > 0 ? cols : default_width
|
131
132
|
else
|
132
133
|
default_width
|
133
134
|
end
|
@@ -138,11 +139,11 @@ class ProgressBar
|
|
138
139
|
|
139
140
|
def show
|
140
141
|
arguments = @format_arguments.map do |method|
|
141
|
-
method =
|
142
|
+
method = format('fmt_%s', method)
|
142
143
|
send(method)
|
143
144
|
end
|
144
145
|
|
145
|
-
line =
|
146
|
+
line = format(@format, *arguments)
|
146
147
|
|
147
148
|
width = get_width
|
148
149
|
if line.length == width - 1
|
@@ -150,7 +151,7 @@ class ProgressBar
|
|
150
151
|
@out.flush
|
151
152
|
elsif line.length >= width
|
152
153
|
@terminal_width = [@terminal_width - (line.length - width + 1), 0].max
|
153
|
-
|
154
|
+
@terminal_width == 0 ? @out.print(line + eol) : show
|
154
155
|
else # line.length < width - 1
|
155
156
|
@terminal_width += width - line.length + 1
|
156
157
|
show
|
@@ -169,16 +170,16 @@ class ProgressBar
|
|
169
170
|
|
170
171
|
# Use "!=" instead of ">" to support negative changes
|
171
172
|
if cur_percentage != prev_percentage ||
|
172
|
-
|
173
|
+
Time.now - @previous_time >= 1 || @finished_p
|
173
174
|
show
|
174
175
|
end
|
175
176
|
end
|
176
177
|
|
177
|
-
public
|
178
|
+
public
|
178
179
|
|
179
180
|
def clear
|
180
181
|
@out.print "\r"
|
181
|
-
@out.print(
|
182
|
+
@out.print(' ' * (get_width - 1))
|
182
183
|
@out.print "\r"
|
183
184
|
end
|
184
185
|
|
@@ -193,30 +194,26 @@ public
|
|
193
194
|
end
|
194
195
|
|
195
196
|
def file_transfer_mode
|
196
|
-
@format_arguments = [
|
197
|
+
@format_arguments = %i[title percentage bar stat_for_file_transfer]
|
197
198
|
end
|
198
199
|
|
199
|
-
|
200
|
-
@format = format
|
201
|
-
end
|
200
|
+
attr_writer :format
|
202
201
|
|
203
|
-
|
204
|
-
@format_arguments = arguments
|
205
|
-
end
|
202
|
+
attr_writer :format_arguments
|
206
203
|
|
207
204
|
def halt
|
208
205
|
@finished_p = true
|
209
206
|
show
|
210
207
|
end
|
211
208
|
|
212
|
-
def inc
|
209
|
+
def inc(step = 1)
|
213
210
|
@current += step
|
214
211
|
@current = @total if @current > @total
|
215
212
|
show_if_needed
|
216
213
|
@previous = @current
|
217
214
|
end
|
218
215
|
|
219
|
-
def set
|
216
|
+
def set(count)
|
220
217
|
if count < 0 || count > @total
|
221
218
|
raise "invalid count: #{count} (total: #{@total})"
|
222
219
|
end
|
data/lib/taps/schema.rb
CHANGED
@@ -9,7 +9,7 @@ module Taps
|
|
9
9
|
|
10
10
|
def dump(database_url)
|
11
11
|
db = Sequel.connect(database_url)
|
12
|
-
db.dump_schema_migration(:
|
12
|
+
db.dump_schema_migration(indexes: false)
|
13
13
|
end
|
14
14
|
|
15
15
|
def dump_table(database_url, table)
|
@@ -17,7 +17,7 @@ module Taps
|
|
17
17
|
<<END_MIG
|
18
18
|
Class.new(Sequel::Migration) do
|
19
19
|
def up
|
20
|
-
#{db.extension(:schema_dumper).dump_table_schema(Sequel.identifier(table.to_sym), :
|
20
|
+
#{db.extension(:schema_dumper).dump_table_schema(Sequel.identifier(table.to_sym), indexes: false)}
|
21
21
|
end
|
22
22
|
|
23
23
|
def down
|
data/lib/taps/server.rb
CHANGED
@@ -12,17 +12,17 @@ module Taps
|
|
12
12
|
|
13
13
|
use Rack::Deflater unless ENV['NO_DEFLATE']
|
14
14
|
|
15
|
-
set :
|
16
|
-
set :
|
15
|
+
set raise_errors: false
|
16
|
+
set show_exceptions: false
|
17
17
|
|
18
18
|
error do
|
19
19
|
e = request.env['sinatra.error']
|
20
20
|
|
21
21
|
puts "ERROR: #{e.class}: #{e.message}"
|
22
22
|
|
23
|
-
if e.
|
24
|
-
content_type
|
25
|
-
halt 412, ::OkJson.encode(
|
23
|
+
if e.is_a?(Taps::BaseError)
|
24
|
+
content_type 'application/json'
|
25
|
+
halt 412, ::OkJson.encode('error_class' => e.class.to_s, 'error_message' => e.message, 'error_backtrace' => e.backtrace.join("\n"))
|
26
26
|
else
|
27
27
|
"Taps Server Error: #{e}\n#{e.backtrace}"
|
28
28
|
end
|
@@ -30,8 +30,8 @@ module Taps
|
|
30
30
|
|
31
31
|
before do
|
32
32
|
unless request.path_info == '/health'
|
33
|
-
major, minor = request.env['HTTP_TAPS_VERSION'].split('.')
|
34
|
-
unless "#{major}.#{minor}"
|
33
|
+
major, minor = request.env['HTTP_TAPS_VERSION'].to_s.split('.')
|
34
|
+
unless Taps.compatible_version == "#{major}.#{minor}"
|
35
35
|
halt 417, "Taps >= v#{Taps.compatible_version}.x is required for this server"
|
36
36
|
end
|
37
37
|
end
|
@@ -39,29 +39,29 @@ module Taps
|
|
39
39
|
|
40
40
|
get '/health' do
|
41
41
|
content_type 'application/json'
|
42
|
-
::OkJson.encode(
|
42
|
+
::OkJson.encode(ok: true)
|
43
43
|
end
|
44
44
|
|
45
45
|
get '/' do
|
46
|
-
|
46
|
+
'hello'
|
47
47
|
end
|
48
48
|
|
49
49
|
post '/sessions' do
|
50
|
-
key = rand(
|
50
|
+
key = rand(9_999_999_999).to_s
|
51
51
|
|
52
|
-
if ENV['NO_DEFAULT_DATABASE_URL']
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
52
|
+
database_url = if ENV['NO_DEFAULT_DATABASE_URL']
|
53
|
+
request.body.string
|
54
|
+
else
|
55
|
+
Taps::Config.database_url || request.body.string
|
56
|
+
end
|
57
57
|
|
58
|
-
DbSession.create(:
|
58
|
+
DbSession.create(key: key, database_url: database_url, started_at: Time.now, last_access: Time.now)
|
59
59
|
|
60
60
|
"/sessions/#{key}"
|
61
61
|
end
|
62
62
|
|
63
63
|
post '/sessions/:key/push/verify_stream' do
|
64
|
-
session = DbSession.filter(:
|
64
|
+
session = DbSession.filter(key: params[:key]).first
|
65
65
|
halt 404 unless session
|
66
66
|
|
67
67
|
state = DataStream.parse_json(params[:state])
|
@@ -75,11 +75,11 @@ module Taps
|
|
75
75
|
end
|
76
76
|
|
77
77
|
content_type 'application/json'
|
78
|
-
::OkJson.encode(
|
78
|
+
::OkJson.encode(state: stream.to_hash)
|
79
79
|
end
|
80
80
|
|
81
81
|
post '/sessions/:key/push/table' do
|
82
|
-
session = DbSession.filter(:
|
82
|
+
session = DbSession.filter(key: params[:key]).first
|
83
83
|
halt 404 unless session
|
84
84
|
|
85
85
|
json = DataStream.parse_json(params[:json])
|
@@ -97,14 +97,14 @@ module Taps
|
|
97
97
|
end
|
98
98
|
|
99
99
|
post '/sessions/:key/push/reset_sequences' do
|
100
|
-
session = DbSession.filter(:
|
100
|
+
session = DbSession.filter(key: params[:key]).first
|
101
101
|
halt 404 unless session
|
102
102
|
|
103
103
|
Taps::Utils.schema_bin(:reset_db_sequences, session.database_url)
|
104
104
|
end
|
105
105
|
|
106
106
|
post '/sessions/:key/push/schema' do
|
107
|
-
session = DbSession.filter(:
|
107
|
+
session = DbSession.filter(key: params[:key]).first
|
108
108
|
halt 404 unless session
|
109
109
|
|
110
110
|
schema_data = request.body.read
|
@@ -112,7 +112,7 @@ module Taps
|
|
112
112
|
end
|
113
113
|
|
114
114
|
post '/sessions/:key/push/indexes' do
|
115
|
-
session = DbSession.filter(:
|
115
|
+
session = DbSession.filter(key: params[:key]).first
|
116
116
|
halt 404 unless session
|
117
117
|
|
118
118
|
index_data = request.body.read
|
@@ -120,14 +120,14 @@ module Taps
|
|
120
120
|
end
|
121
121
|
|
122
122
|
post '/sessions/:key/pull/schema' do
|
123
|
-
session = DbSession.filter(:
|
123
|
+
session = DbSession.filter(key: params[:key]).first
|
124
124
|
halt 404 unless session
|
125
125
|
|
126
126
|
Taps::Utils.schema_bin(:dump_table, session.database_url, params[:table_name])
|
127
127
|
end
|
128
128
|
|
129
129
|
get '/sessions/:key/pull/indexes' do
|
130
|
-
session = DbSession.filter(:
|
130
|
+
session = DbSession.filter(key: params[:key]).first
|
131
131
|
halt 404 unless session
|
132
132
|
|
133
133
|
content_type 'application/json'
|
@@ -135,7 +135,7 @@ module Taps
|
|
135
135
|
end
|
136
136
|
|
137
137
|
get '/sessions/:key/pull/table_names' do
|
138
|
-
session = DbSession.filter(:
|
138
|
+
session = DbSession.filter(key: params[:key]).first
|
139
139
|
halt 404 unless session
|
140
140
|
|
141
141
|
tables = []
|
@@ -148,18 +148,18 @@ module Taps
|
|
148
148
|
end
|
149
149
|
|
150
150
|
post '/sessions/:key/pull/table_count' do
|
151
|
-
session = DbSession.filter(:
|
151
|
+
session = DbSession.filter(key: params[:key]).first
|
152
152
|
halt 404 unless session
|
153
153
|
|
154
154
|
count = 0
|
155
155
|
session.conn do |db|
|
156
|
-
count = db[
|
156
|
+
count = db[params[:table].to_sym.identifier].count
|
157
157
|
end
|
158
158
|
count.to_s
|
159
159
|
end
|
160
160
|
|
161
161
|
post '/sessions/:key/pull/table' do
|
162
|
-
session = DbSession.filter(:
|
162
|
+
session = DbSession.filter(key: params[:key]).first
|
163
163
|
halt 404 unless session
|
164
164
|
|
165
165
|
encoded_data = nil
|
@@ -172,15 +172,15 @@ module Taps
|
|
172
172
|
end
|
173
173
|
|
174
174
|
checksum = Taps::Utils.checksum(encoded_data).to_s
|
175
|
-
json = ::OkJson.encode(
|
175
|
+
json = ::OkJson.encode(checksum: checksum, state: stream.to_hash)
|
176
176
|
|
177
177
|
content, content_type_value = Taps::Multipart.create do |r|
|
178
|
-
r.attach :
|
179
|
-
|
180
|
-
|
181
|
-
r.attach :
|
182
|
-
|
183
|
-
|
178
|
+
r.attach name: :encoded_data,
|
179
|
+
payload: encoded_data,
|
180
|
+
content_type: 'application/octet-stream'
|
181
|
+
r.attach name: :json,
|
182
|
+
payload: json,
|
183
|
+
content_type: 'application/json'
|
184
184
|
end
|
185
185
|
|
186
186
|
content_type content_type_value
|
@@ -188,13 +188,12 @@ module Taps
|
|
188
188
|
end
|
189
189
|
|
190
190
|
delete '/sessions/:key' do
|
191
|
-
session = DbSession.filter(:
|
191
|
+
session = DbSession.filter(key: params[:key]).first
|
192
192
|
halt 404 unless session
|
193
193
|
|
194
194
|
session.destroy
|
195
195
|
|
196
|
-
|
196
|
+
'ok'
|
197
197
|
end
|
198
|
-
|
199
198
|
end
|
200
199
|
end
|
data/lib/taps/utils.rb
CHANGED
@@ -31,45 +31,41 @@ module Taps
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def base64encode(data)
|
34
|
-
[data].pack(
|
34
|
+
[data].pack('m')
|
35
35
|
end
|
36
36
|
|
37
37
|
def base64decode(data)
|
38
|
-
data.unpack(
|
38
|
+
data.unpack('m').first
|
39
39
|
end
|
40
40
|
|
41
|
-
def format_data(data, opts={})
|
42
|
-
return {} if data.
|
41
|
+
def format_data(data, opts = {})
|
42
|
+
return {} if data.empty?
|
43
43
|
string_columns = opts[:string_columns] || []
|
44
44
|
schema = opts[:schema] || []
|
45
45
|
table = opts[:table]
|
46
46
|
|
47
|
-
max_lengths = schema.
|
48
|
-
if meta[:db_type] =~ /^varchar\((\d+)\)/
|
49
|
-
hash.update(column => $1.to_i)
|
50
|
-
end
|
51
|
-
hash
|
47
|
+
max_lengths = schema.each_with_object({}) do |(column, meta), hash|
|
48
|
+
hash.update(column => Regexp.last_match(1).to_i) if meta[:db_type] =~ /^varchar\((\d+)\)/
|
52
49
|
end
|
53
50
|
|
54
51
|
header = data[0].keys
|
55
52
|
only_data = data.collect do |row|
|
56
53
|
row = blobs_to_string(row, string_columns)
|
57
54
|
row.each do |column, value|
|
58
|
-
|
59
|
-
|
55
|
+
next unless value.to_s.length > (max_lengths[column] || value.to_s.length)
|
56
|
+
raise Taps::InvalidData, <<-ERROR
|
60
57
|
Detected value that exceeds the length limitation of its column. This is
|
61
58
|
generally due to the fact that SQLite does not enforce length restrictions.
|
62
59
|
|
63
60
|
Table : #{table}
|
64
61
|
Column : #{column}
|
65
|
-
Type : #{schema.detect{|s| s.first == column}.last[:db_type]}
|
62
|
+
Type : #{schema.detect { |s| s.first == column }.last[:db_type]}
|
66
63
|
Value : #{value}
|
67
|
-
ERROR
|
68
|
-
end
|
64
|
+
ERROR
|
69
65
|
end
|
70
66
|
header.collect { |h| row[h] }
|
71
67
|
end
|
72
|
-
{ :
|
68
|
+
{ header: header, data: only_data }
|
73
69
|
end
|
74
70
|
|
75
71
|
# mysql text and blobs fields are handled the same way internally
|
@@ -87,9 +83,9 @@ ERROR
|
|
87
83
|
end
|
88
84
|
|
89
85
|
def blobs_to_string(row, columns)
|
90
|
-
return row if columns.
|
86
|
+
return row if columns.empty?
|
91
87
|
columns.each do |c|
|
92
|
-
row[c] = row[c].to_s if row[c].
|
88
|
+
row[c] = row[c].to_s if row[c].is_a?(Sequel::SQL::Blob)
|
93
89
|
end
|
94
90
|
row
|
95
91
|
end
|
@@ -138,42 +134,43 @@ ERROR
|
|
138
134
|
end
|
139
135
|
|
140
136
|
def single_integer_primary_key(db, table)
|
141
|
-
table = table.to_sym.identifier unless table.
|
137
|
+
table = table.to_sym.identifier unless table.is_a?(Sequel::SQL::Identifier)
|
142
138
|
keys = db.schema(table).select { |c| c[1][:primary_key] }
|
143
|
-
|
139
|
+
!keys.nil? && (keys.size == 1) && (keys[0][1][:type] == :integer)
|
144
140
|
end
|
145
141
|
|
146
142
|
def order_by(db, table)
|
147
143
|
pkey = primary_key(db, table)
|
148
144
|
if pkey
|
149
|
-
pkey.
|
145
|
+
pkey.is_a?(Array) ? pkey : [pkey.to_sym]
|
150
146
|
else
|
151
|
-
table = table.to_sym.identifier unless table.
|
147
|
+
table = table.to_sym.identifier unless table.is_a?(Sequel::SQL::Identifier)
|
152
148
|
db[table].columns
|
153
149
|
end
|
154
150
|
end
|
155
151
|
|
156
|
-
|
157
152
|
# try to detect server side errors to
|
158
153
|
# give the client a more useful error message
|
159
|
-
def server_error_handling
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
raise
|
167
|
-
end
|
154
|
+
def server_error_handling
|
155
|
+
yield
|
156
|
+
rescue Sequel::DatabaseError => e
|
157
|
+
if e.message =~ /duplicate key value/i
|
158
|
+
raise Taps::DuplicatePrimaryKeyError, e.message
|
159
|
+
else
|
160
|
+
raise
|
168
161
|
end
|
169
162
|
end
|
170
163
|
|
171
164
|
def reraise_server_exception(e)
|
172
|
-
if e.
|
165
|
+
if e.is_a?(RestClient::Exception)
|
173
166
|
if e.respond_to?(:response) && e.response.headers[:content_type] == 'application/json'
|
174
167
|
json = ::OkJson.decode(e.response.to_s)
|
175
|
-
klass =
|
176
|
-
|
168
|
+
klass = begin
|
169
|
+
eval(json['error_class'])
|
170
|
+
rescue
|
171
|
+
nil
|
172
|
+
end
|
173
|
+
raise klass.new(json['error_message'], backtrace: json['error_backtrace']) if klass
|
177
174
|
end
|
178
175
|
end
|
179
176
|
raise e
|