sanford 0.14.0 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/sanford/connection_handler.rb +57 -44
- data/lib/sanford/error_handler.rb +44 -20
- data/lib/sanford/process.rb +9 -19
- data/lib/sanford/server.rb +47 -7
- data/lib/sanford/server_data.rb +8 -1
- data/lib/sanford/version.rb +1 -1
- data/sanford.gemspec +2 -2
- data/test/support/app_server.rb +5 -4
- data/test/support/factory.rb +8 -0
- data/test/unit/connection_handler_tests.rb +13 -15
- data/test/unit/error_handler_tests.rb +245 -109
- data/test/unit/process_tests.rb +10 -22
- data/test/unit/server_data_tests.rb +32 -16
- data/test/unit/server_tests.rb +99 -17
- metadata +10 -10
@@ -7,10 +7,6 @@ module Sanford
|
|
7
7
|
|
8
8
|
class ConnectionHandler
|
9
9
|
|
10
|
-
ProcessedService = Struct.new(
|
11
|
-
:request, :handler_class, :response, :exception, :time_taken
|
12
|
-
)
|
13
|
-
|
14
10
|
attr_reader :server_data, :connection
|
15
11
|
attr_reader :logger
|
16
12
|
|
@@ -38,47 +34,52 @@ module Sanford
|
|
38
34
|
protected
|
39
35
|
|
40
36
|
def run!
|
41
|
-
|
37
|
+
processed_service = ProcessedService.new
|
42
38
|
begin
|
43
39
|
request = Sanford::Protocol::Request.parse(@connection.read_data)
|
44
40
|
self.log_request(request)
|
45
|
-
|
41
|
+
processed_service.request = request
|
46
42
|
|
47
43
|
route = @server_data.route_for(request.name)
|
48
44
|
self.log_handler_class(route.handler_class)
|
49
|
-
|
45
|
+
processed_service.handler_class = route.handler_class
|
50
46
|
|
51
47
|
response = route.run(request, @server_data)
|
52
|
-
|
48
|
+
processed_service.response = response
|
53
49
|
rescue StandardError => exception
|
54
|
-
self.handle_exception(
|
50
|
+
self.handle_exception(exception, @server_data, processed_service)
|
55
51
|
ensure
|
56
|
-
self.write_response(
|
52
|
+
self.write_response(processed_service)
|
57
53
|
end
|
58
|
-
|
54
|
+
processed_service
|
59
55
|
end
|
60
56
|
|
61
|
-
def write_response(
|
57
|
+
def write_response(processed_service)
|
62
58
|
begin
|
63
|
-
@connection.write_data
|
59
|
+
@connection.write_data processed_service.response.to_hash
|
64
60
|
rescue StandardError => exception
|
65
|
-
|
66
|
-
|
61
|
+
processed_service = self.handle_exception(
|
62
|
+
exception,
|
63
|
+
@server_data,
|
64
|
+
processed_service
|
65
|
+
)
|
66
|
+
@connection.write_data processed_service.response.to_hash
|
67
67
|
end
|
68
68
|
@connection.close_write
|
69
|
-
|
69
|
+
processed_service
|
70
70
|
end
|
71
71
|
|
72
|
-
def handle_exception(
|
73
|
-
error_handler = Sanford::ErrorHandler.new(
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
72
|
+
def handle_exception(exception, server_data, processed_service)
|
73
|
+
error_handler = Sanford::ErrorHandler.new(exception, {
|
74
|
+
:server_data => server_data,
|
75
|
+
:request => processed_service.request,
|
76
|
+
:handler_class => processed_service.handler_class,
|
77
|
+
:response => processed_service.response
|
78
|
+
})
|
79
|
+
processed_service.response = error_handler.run
|
80
|
+
processed_service.exception = error_handler.exception
|
81
|
+
self.log_exception(processed_service.exception)
|
82
|
+
processed_service
|
82
83
|
end
|
83
84
|
|
84
85
|
def raise_if_debugging!(exception)
|
@@ -101,18 +102,7 @@ module Sanford
|
|
101
102
|
def log_complete(processed_service)
|
102
103
|
log_verbose "===== Completed in #{processed_service.time_taken}ms " \
|
103
104
|
"#{processed_service.response.status} ====="
|
104
|
-
|
105
|
-
'time' => processed_service.time_taken,
|
106
|
-
'handler' => processed_service.handler_class
|
107
|
-
}
|
108
|
-
if processed_service.response
|
109
|
-
summary_line_args['status'] = processed_service.response.code
|
110
|
-
end
|
111
|
-
if (request = processed_service.request)
|
112
|
-
summary_line_args['service'] = request.name
|
113
|
-
summary_line_args['params'] = request.params
|
114
|
-
end
|
115
|
-
log_summary SummaryLine.new(summary_line_args)
|
105
|
+
log_summary build_summary_line(processed_service)
|
116
106
|
end
|
117
107
|
|
118
108
|
def log_exception(exception)
|
@@ -129,6 +119,32 @@ module Sanford
|
|
129
119
|
self.logger.summary.send(level, "[Sanford] #{message}")
|
130
120
|
end
|
131
121
|
|
122
|
+
def build_summary_line(processed_service)
|
123
|
+
summary_line_args = {
|
124
|
+
'time' => processed_service.time_taken,
|
125
|
+
'handler' => processed_service.handler_class
|
126
|
+
}
|
127
|
+
if (request = processed_service.request)
|
128
|
+
summary_line_args['service'] = request.name
|
129
|
+
summary_line_args['params'] = request.params.to_hash
|
130
|
+
end
|
131
|
+
if (response = processed_service.response)
|
132
|
+
summary_line_args['status'] = response.code
|
133
|
+
end
|
134
|
+
if (exception = processed_service.exception)
|
135
|
+
summary_line_args['error'] = "#{exception.class}: #{exception.message}"
|
136
|
+
end
|
137
|
+
SummaryLine.new(summary_line_args)
|
138
|
+
end
|
139
|
+
|
140
|
+
module SummaryLine
|
141
|
+
KEYS = %w{time status handler service params error}.freeze
|
142
|
+
|
143
|
+
def self.new(line_attrs)
|
144
|
+
KEYS.map{ |k| "#{k}=#{line_attrs[k].inspect}" }.join(' ')
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
132
148
|
module RoundedTime
|
133
149
|
ROUND_PRECISION = 2
|
134
150
|
ROUND_MODIFIER = 10 ** ROUND_PRECISION
|
@@ -137,12 +153,9 @@ module Sanford
|
|
137
153
|
end
|
138
154
|
end
|
139
155
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
attr_keys.map{ |k| "#{k}=#{line_attrs[k].inspect}" }.join(' ')
|
144
|
-
end
|
145
|
-
end
|
156
|
+
ProcessedService = Struct.new(
|
157
|
+
:request, :handler_class, :response, :exception, :time_taken
|
158
|
+
)
|
146
159
|
|
147
160
|
end
|
148
161
|
|
@@ -1,16 +1,15 @@
|
|
1
|
-
require 'ostruct'
|
2
1
|
require 'sanford-protocol'
|
3
2
|
|
4
3
|
module Sanford
|
5
4
|
|
6
5
|
class ErrorHandler
|
7
6
|
|
8
|
-
attr_reader :exception, :
|
9
|
-
attr_reader :error_procs
|
7
|
+
attr_reader :exception, :context, :error_procs
|
10
8
|
|
11
|
-
def initialize(exception,
|
12
|
-
@exception
|
13
|
-
@
|
9
|
+
def initialize(exception, context_hash)
|
10
|
+
@exception = exception
|
11
|
+
@context = ErrorContext.new(context_hash)
|
12
|
+
@error_procs = context_hash[:server_data].error_procs.reverse
|
14
13
|
end
|
15
14
|
|
16
15
|
# The exception that we are generating a response for can change in the case
|
@@ -24,44 +23,69 @@ module Sanford
|
|
24
23
|
@error_procs.each do |error_proc|
|
25
24
|
result = nil
|
26
25
|
begin
|
27
|
-
result = error_proc.call(@exception, @
|
26
|
+
result = error_proc.call(@exception, @context)
|
28
27
|
rescue StandardError => proc_exception
|
29
28
|
@exception = proc_exception
|
30
29
|
end
|
31
|
-
response ||=
|
30
|
+
response ||= response_from_proc(result)
|
32
31
|
end
|
33
|
-
response ||
|
32
|
+
response || response_from_exception(@exception)
|
34
33
|
end
|
35
34
|
|
36
|
-
|
35
|
+
private
|
37
36
|
|
38
37
|
def response_from_proc(result)
|
39
|
-
|
40
|
-
when Sanford::Protocol::Response
|
38
|
+
if result.kind_of?(Sanford::Protocol::Response)
|
41
39
|
result
|
42
|
-
|
40
|
+
elsif result.kind_of?(Integer) || result.kind_of?(Symbol)
|
43
41
|
build_response result
|
44
42
|
end
|
45
43
|
end
|
46
44
|
|
47
45
|
def response_from_exception(exception)
|
48
|
-
|
49
|
-
|
46
|
+
if exception.kind_of?(Sanford::Protocol::BadMessageError) ||
|
47
|
+
exception.kind_of?(Sanford::Protocol::Request::InvalidError)
|
50
48
|
build_response :bad_request, :message => exception.message
|
51
|
-
|
49
|
+
elsif exception.kind_of?(Sanford::NotFoundError)
|
52
50
|
build_response :not_found
|
53
|
-
|
51
|
+
elsif exception.kind_of?(Sanford::Protocol::TimeoutError)
|
54
52
|
build_response :timeout
|
55
|
-
|
53
|
+
else
|
56
54
|
build_response :error, :message => "An unexpected error occurred."
|
57
55
|
end
|
58
56
|
end
|
59
57
|
|
60
58
|
def build_response(status, options = nil)
|
61
|
-
options
|
62
|
-
Sanford::Protocol::Response.new(
|
59
|
+
options ||= {}
|
60
|
+
Sanford::Protocol::Response.new(
|
61
|
+
[status, options[:message]],
|
62
|
+
options[:data]
|
63
|
+
)
|
63
64
|
end
|
64
65
|
|
65
66
|
end
|
66
67
|
|
68
|
+
class ErrorContext
|
69
|
+
attr_reader :server_data
|
70
|
+
attr_reader :request, :handler_class, :response
|
71
|
+
|
72
|
+
def initialize(args)
|
73
|
+
@server_data = args[:server_data]
|
74
|
+
@request = args[:request]
|
75
|
+
@handler_class = args[:handler_class]
|
76
|
+
@response = args[:response]
|
77
|
+
end
|
78
|
+
|
79
|
+
def ==(other)
|
80
|
+
if other.kind_of?(self.class)
|
81
|
+
self.server_data == other.server_data &&
|
82
|
+
self.request == other.request &&
|
83
|
+
self.handler_class == other.handler_class &&
|
84
|
+
self.response == other.response
|
85
|
+
else
|
86
|
+
super
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
67
91
|
end
|
data/lib/sanford/process.rb
CHANGED
@@ -14,20 +14,19 @@ module Sanford
|
|
14
14
|
@pid_file = PIDFile.new(@server.pid_file)
|
15
15
|
@restart_cmd = RestartCmd.new
|
16
16
|
|
17
|
-
@server_ip
|
18
|
-
@server_port =
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
@
|
23
|
-
@listen_args = @server_fd ? [ @server_fd ] : [ @server_ip, @server_port ]
|
17
|
+
@server_ip = @server.configured_ip
|
18
|
+
@server_port = @server.configured_port
|
19
|
+
@server_fd = if !ENV['SANFORD_SERVER_FD'].to_s.empty?
|
20
|
+
ENV['SANFORD_SERVER_FD'].to_i
|
21
|
+
end
|
22
|
+
@listen_args = @server_fd ? [@server_fd] : [@server_ip, @server_port]
|
24
23
|
|
25
24
|
@name = "sanford-#{@server.name}-#{@server_ip}-#{@server_port}"
|
26
25
|
|
27
|
-
@client_fds =
|
26
|
+
@client_fds = ENV['SANFORD_CLIENT_FDS'].to_s.split(',').map(&:to_i)
|
28
27
|
|
29
|
-
@daemonize
|
30
|
-
@skip_daemonize =
|
28
|
+
@daemonize = !!options[:daemonize]
|
29
|
+
@skip_daemonize = !ENV['SANFORD_SKIP_DAEMONIZE'].to_s.empty?
|
31
30
|
end
|
32
31
|
|
33
32
|
def run
|
@@ -74,15 +73,6 @@ module Sanford
|
|
74
73
|
@restart_cmd.run
|
75
74
|
end
|
76
75
|
|
77
|
-
def default_if_blank(value, default, &block)
|
78
|
-
ignore_if_blank(value, &block) || default
|
79
|
-
end
|
80
|
-
|
81
|
-
def ignore_if_blank(value, &block)
|
82
|
-
block ||= proc{ |v| v }
|
83
|
-
block.call(value) if value && !value.empty?
|
84
|
-
end
|
85
|
-
|
86
76
|
end
|
87
77
|
|
88
78
|
class RestartCmd
|
data/lib/sanford/server.rb
CHANGED
@@ -28,7 +28,7 @@ module Sanford
|
|
28
28
|
def initialize
|
29
29
|
self.class.configuration.validate!
|
30
30
|
@server_data = ServerData.new(self.class.configuration.to_hash)
|
31
|
-
@dat_tcp_server =
|
31
|
+
@dat_tcp_server = build_dat_tcp_server
|
32
32
|
rescue InvalidError => exception
|
33
33
|
exception.set_backtrace(caller)
|
34
34
|
raise exception
|
@@ -83,6 +83,8 @@ module Sanford
|
|
83
83
|
@dat_tcp_server.listen(*args) do |server_socket|
|
84
84
|
configure_tcp_server(server_socket)
|
85
85
|
end
|
86
|
+
@server_data.ip = self.ip
|
87
|
+
@server_data.port = self.port
|
86
88
|
end
|
87
89
|
|
88
90
|
def start(*args)
|
@@ -107,6 +109,18 @@ module Sanford
|
|
107
109
|
|
108
110
|
private
|
109
111
|
|
112
|
+
def build_dat_tcp_server
|
113
|
+
s = DatTCP::Server.new{ |socket| serve(socket) }
|
114
|
+
|
115
|
+
# add any configured callbacks
|
116
|
+
self.server_data.worker_start_procs.each{ |p| s.on_worker_start(&p) }
|
117
|
+
self.server_data.worker_shutdown_procs.each{ |p| s.on_worker_shutdown(&p) }
|
118
|
+
self.server_data.worker_sleep_procs.each{ |p| s.on_worker_sleep(&p) }
|
119
|
+
self.server_data.worker_wakeup_procs.each{ |p| s.on_worker_wakeup(&p) }
|
120
|
+
|
121
|
+
s
|
122
|
+
end
|
123
|
+
|
110
124
|
def serve(socket)
|
111
125
|
connection = Connection.new(socket)
|
112
126
|
if !keep_alive_connection?(connection)
|
@@ -171,6 +185,22 @@ module Sanford
|
|
171
185
|
self.configuration.error_procs << block
|
172
186
|
end
|
173
187
|
|
188
|
+
def on_worker_start(&block)
|
189
|
+
self.configuration.worker_start_procs << block
|
190
|
+
end
|
191
|
+
|
192
|
+
def on_worker_shutdown(&block)
|
193
|
+
self.configuration.worker_shutdown_procs << block
|
194
|
+
end
|
195
|
+
|
196
|
+
def on_worker_sleep(&block)
|
197
|
+
self.configuration.worker_sleep_procs << block
|
198
|
+
end
|
199
|
+
|
200
|
+
def on_worker_wakeup(&block)
|
201
|
+
self.configuration.worker_wakeup_procs << block
|
202
|
+
end
|
203
|
+
|
174
204
|
def router(value = nil, &block)
|
175
205
|
self.configuration.router = value if !value.nil?
|
176
206
|
self.configuration.router.instance_eval(&block) if block
|
@@ -244,7 +274,7 @@ module Sanford
|
|
244
274
|
include NsOptions::Proxy
|
245
275
|
|
246
276
|
option :name, String, :required => true
|
247
|
-
option :ip, String, :required => true
|
277
|
+
option :ip, String, :required => true
|
248
278
|
option :port, Integer, :required => true
|
249
279
|
option :pid_file, Pathname
|
250
280
|
|
@@ -256,12 +286,18 @@ module Sanford
|
|
256
286
|
|
257
287
|
attr_accessor :init_procs, :error_procs
|
258
288
|
attr_accessor :router
|
289
|
+
attr_reader :worker_start_procs, :worker_shutdown_procs
|
290
|
+
attr_reader :worker_sleep_procs, :worker_wakeup_procs
|
259
291
|
|
260
292
|
def initialize(values = nil)
|
261
293
|
super(values)
|
294
|
+
self.ip = !(v = ENV['SANFORD_IP'].to_s).empty? ? v : '0.0.0.0'
|
295
|
+
self.port = !(v = ENV['SANFORD_PORT'].to_s).empty? ? v : nil
|
262
296
|
@init_procs, @error_procs = [], []
|
297
|
+
@worker_start_procs, @worker_shutdown_procs = [], []
|
298
|
+
@worker_sleep_procs, @worker_wakeup_procs = [], []
|
263
299
|
@router = Sanford::Router.new
|
264
|
-
@valid
|
300
|
+
@valid = nil
|
265
301
|
end
|
266
302
|
|
267
303
|
def routes
|
@@ -270,10 +306,14 @@ module Sanford
|
|
270
306
|
|
271
307
|
def to_hash
|
272
308
|
super.merge({
|
273
|
-
:init_procs
|
274
|
-
:error_procs
|
275
|
-
:
|
276
|
-
:
|
309
|
+
:init_procs => self.init_procs,
|
310
|
+
:error_procs => self.error_procs,
|
311
|
+
:worker_start_procs => self.worker_start_procs,
|
312
|
+
:worker_shutdown_procs => self.worker_shutdown_procs,
|
313
|
+
:worker_sleep_procs => self.worker_sleep_procs,
|
314
|
+
:worker_wakeup_procs => self.worker_wakeup_procs,
|
315
|
+
:router => self.router,
|
316
|
+
:routes => self.routes
|
277
317
|
})
|
278
318
|
end
|
279
319
|
|
data/lib/sanford/server_data.rb
CHANGED
@@ -8,12 +8,14 @@ module Sanford
|
|
8
8
|
# NsOptions overhead when reading them while handling a request.
|
9
9
|
|
10
10
|
attr_reader :name
|
11
|
-
attr_reader :ip, :port
|
12
11
|
attr_reader :pid_file
|
13
12
|
attr_reader :receives_keep_alive
|
14
13
|
attr_reader :verbose_logging, :logger, :template_source
|
15
14
|
attr_reader :init_procs, :error_procs
|
15
|
+
attr_reader :worker_start_procs, :worker_shutdown_procs
|
16
|
+
attr_reader :worker_sleep_procs, :worker_wakeup_procs
|
16
17
|
attr_reader :router, :routes
|
18
|
+
attr_accessor :ip, :port
|
17
19
|
|
18
20
|
def initialize(args = nil)
|
19
21
|
args ||= {}
|
@@ -31,6 +33,11 @@ module Sanford
|
|
31
33
|
@init_procs = args[:init_procs] || []
|
32
34
|
@error_procs = args[:error_procs] || []
|
33
35
|
|
36
|
+
@worker_start_procs = args[:worker_start_procs]
|
37
|
+
@worker_shutdown_procs = args[:worker_shutdown_procs]
|
38
|
+
@worker_sleep_procs = args[:worker_sleep_procs]
|
39
|
+
@worker_wakeup_procs = args[:worker_wakeup_procs]
|
40
|
+
|
34
41
|
@router = args[:router]
|
35
42
|
@routes = build_routes(args[:routes] || [])
|
36
43
|
end
|
data/lib/sanford/version.rb
CHANGED
data/sanford.gemspec
CHANGED
@@ -18,9 +18,9 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
19
|
gem.require_paths = ["lib"]
|
20
20
|
|
21
|
-
gem.add_dependency("dat-tcp", ["~> 0.
|
21
|
+
gem.add_dependency("dat-tcp", ["~> 0.7"])
|
22
22
|
gem.add_dependency("ns-options", ["~> 1.1"])
|
23
23
|
gem.add_dependency("sanford-protocol", ["~> 0.11"])
|
24
24
|
|
25
|
-
gem.add_development_dependency("assert", ["~> 2.
|
25
|
+
gem.add_development_dependency("assert", ["~> 2.15"])
|
26
26
|
end
|
data/test/support/app_server.rb
CHANGED
@@ -21,7 +21,7 @@ class AppServer
|
|
21
21
|
include Sanford::Server
|
22
22
|
|
23
23
|
name 'app'
|
24
|
-
ip '
|
24
|
+
ip '127.0.0.1'
|
25
25
|
port 12000
|
26
26
|
|
27
27
|
receives_keep_alive true
|
@@ -45,9 +45,10 @@ class AppServer
|
|
45
45
|
template_source s
|
46
46
|
end
|
47
47
|
|
48
|
-
error do |exception,
|
49
|
-
if request && request.name == 'custom_error'
|
50
|
-
data = "The server on
|
48
|
+
error do |exception, context|
|
49
|
+
if context.request && context.request.name == 'custom_error'
|
50
|
+
data = "The server on " \
|
51
|
+
"#{context.server_data.ip}:#{context.server_data.port} " \
|
51
52
|
"threw a #{exception.class}."
|
52
53
|
Sanford::Protocol::Response.new(200, data)
|
53
54
|
end
|
data/test/support/factory.rb
CHANGED
@@ -3,4 +3,12 @@ require 'assert/factory'
|
|
3
3
|
module Factory
|
4
4
|
extend Assert::Factory
|
5
5
|
|
6
|
+
def self.exception(klass = nil, message = nil)
|
7
|
+
klass ||= StandardError
|
8
|
+
message ||= Factory.text
|
9
|
+
exception = nil
|
10
|
+
begin; raise(klass, message); rescue StandardError => exception; end
|
11
|
+
exception
|
12
|
+
end
|
13
|
+
|
6
14
|
end
|
@@ -89,12 +89,11 @@ class Sanford::ConnectionHandler
|
|
89
89
|
setup do
|
90
90
|
Assert.stub(@route, :run){ raise @exception }
|
91
91
|
|
92
|
-
error_handler = Sanford::ErrorHandler.new(
|
93
|
-
@
|
94
|
-
@
|
95
|
-
|
96
|
-
|
97
|
-
@expected_response = error_handler.run
|
92
|
+
error_handler = Sanford::ErrorHandler.new(@exception, {
|
93
|
+
:server_data => @server_data,
|
94
|
+
:request => @request
|
95
|
+
})
|
96
|
+
@expected_response = error_handler.run
|
98
97
|
@expected_exception = error_handler.exception
|
99
98
|
|
100
99
|
@processed_service = @connection_handler.run
|
@@ -117,16 +116,13 @@ class Sanford::ConnectionHandler
|
|
117
116
|
class RunWithExceptionWhileWritingTests < InitTests
|
118
117
|
desc "and run with an exception thrown while writing the response"
|
119
118
|
setup do
|
120
|
-
Assert.stub(@route, :run){ @response }
|
121
|
-
|
122
119
|
@connection.raise_on_write = true
|
123
120
|
|
124
|
-
error_handler = Sanford::ErrorHandler.new(
|
125
|
-
@
|
126
|
-
@
|
127
|
-
|
128
|
-
|
129
|
-
@expected_response = error_handler.run
|
121
|
+
error_handler = Sanford::ErrorHandler.new(@connection.write_exception, {
|
122
|
+
:server_data => @server_data,
|
123
|
+
:request => @request
|
124
|
+
})
|
125
|
+
@expected_response = error_handler.run
|
130
126
|
@expected_exception = error_handler.exception
|
131
127
|
|
132
128
|
@processed_service = @connection_handler.run
|
@@ -217,12 +213,14 @@ class Sanford::ConnectionHandler
|
|
217
213
|
should "have logged the service" do
|
218
214
|
time_taken = @processed_service.time_taken
|
219
215
|
status = @processed_service.response.status.to_i
|
216
|
+
exception_msg = "#{@exception.class}: #{@exception.message}"
|
220
217
|
expected = "[Sanford] " \
|
221
218
|
"time=#{time_taken} " \
|
222
219
|
"status=#{status} " \
|
223
220
|
"handler=#{@route.handler_class} " \
|
224
221
|
"service=#{@request.name.inspect} " \
|
225
|
-
"params=#{@request.params.inspect}"
|
222
|
+
"params=#{@request.params.inspect} " \
|
223
|
+
"error=#{exception_msg.inspect}"
|
226
224
|
assert_equal expected, subject.info_logged.join
|
227
225
|
end
|
228
226
|
|