-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Strange behavior in modular application #1227
Comments
You are seeing this behavior because you are using the three controllers as middleware. This is exactly the expected behavior: the inner-most Rack application processes the request and passes the response to the second inner-most Rack application, and so forth and so on. Because all the controllers inherit the same error-handler, they all apply the same logic to the response. If you can explain what you are trying to do, we might be able to help you figure out the best way to do it. |
@mwpastore Maybe i misunderstood something, I just want use my own error page template. The answer in this link is the right way? I'm a beginner in Ruby... |
Your error handler is fine, but the way you're structuring your controllers and middleware stack is causing the nesting. All of your controllers inherit the error handler from ApplicationController and apply it on error 403. There are a few different ways to tackle this architectural problem. To do it like you're trying to do it, you can put your error-handling logic in its own middleware and include it at the top of the stack, like so: # test.ru
require 'json'
require 'sinatra/base'
class ErrorController < Sinatra::Base
error 403 do
{ code: status, message: body.join }.to_json
end
end
class ApplicationController < Sinatra::Base
get '/' do
'hello'
end
end
class AController < ApplicationController
get '/a' do
halt 403, 'Oooooops, A'
end
end
class BController < ApplicationController
get '/b' do
halt 403, 'Oooooops, B'
end
end
class CController < ApplicationController
get '/c' do
halt 403, 'Oooooops, C'
end
end
use ErrorController
use AController
use BController
use CController
run ApplicationController Another option is to use Rack::URLMap instead of (or alongside) a middleware stack, and namespace your controllers: # test.ru
require 'json'
require 'sinatra/base'
class ApplicationController < Sinatra::Base
error 403 do
{ code: status, message: body.join }.to_json
end
get '/' do
'hello'
end
end
class AController < ApplicationController
get '/' do
halt 403, 'Oooooops, A'
end
end
class BController < ApplicationController
get '/' do
halt 403, 'Oooooops, B'
end
end
class CController < ApplicationController
get '/' do
halt 403, 'Oooooops, C'
end
end
run Rack::URLMap.new(
'/a' => AController,
'/b' => BController,
'/c' => CController,
'/' => ApplicationController
) Now the routing is done entirely in Rack before the requests hit any of the Sinatra controllers. These are just some options. As you're getting started, I would recommend you continue learning Ruby and dig into the philosophy of Rack a bit more. It's useful to keep in mind that Sinatra is a relatively thin DSL on top of Rack and isn't very opinionated. |
Thank you for the code and advice. I will continue learn Ruby and it's philosophy in depth. This is my first Ruby + Sinatra project after some fragmented time learning. I think i should forget some experience in other language, just think it in the 'Ruby way'. BTW: Sorry for my bad English, hope you can understand it. |
Step:
Add "error 403 do ... end" in application controller , and return {code: status, message: body}
Add halt 403, 'a' in AController
Add halt 403, 'b' in BController
Add halt 403, 'c' in CController
Try request url '/a', got
{"code":403,"message":["Oooooops, A"]}
Try request url '/b/, got
{"code":403,"message":"{\"code\":403,\"message\":\"Oooooops, B\"}"}
Try request url '/c', got
{"code":403,"message":["{\"code\":403,\"message\":[\"{\\\"code\\\":403,\\\"message\\\":[\\\"Oooooops, C\\\"]}\"]}"]}
That's the problem, Why response like a "Matryoshka doll"?
How many times body repeat is depend on 'use' order in
config.ru
Here is sample code, run it with
bundle install
thenrackup -p 9192
sample_code.tar.gz
The text was updated successfully, but these errors were encountered: