sanford 0.14.0 → 0.15.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/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
|
|