在已占用的端口上运行Sinatra时,避免显示回溯

时间:2018-10-20 09:51:49

标签: ruby sinatra

当Sinatra无法正确运行服务器时(例如,由于端口已在使用中),阻止Sinatra显示完整回溯的正确方法是什么?

这是一个示例sinatra应用程序:

# test.rb
require 'sinatra'
require 'bundler/inline'

gemfile do
  gem 'sinatra'
  gem 'puma'
end

set :bind, "0.0.0.0"
set :port, 3000

get '/' do
  "hello"
end

然后,用ruby test.rb运行一次,以占用端口。

然后,在另一个终端窗口中再次运行它,并显示此完整的错误回溯:

$ ruby test.rb
== Sinatra (v2.0.4) has taken the stage on 3000 for development with backup from Puma
Puma starting in single mode...
* Version 3.12.0 (ruby 2.5.0-p0), codename: Llamas in Pajamas
* Min threads: 0, max threads: 16
* Environment: development
* Listening on tcp://0.0.0.0:3000
== Someone is already performing on port 3000!
Traceback (most recent call last):
        5: from /store/gems/ruby-2.5.0/gems/sinatra-2.0.4/lib/sinatra/main.rb:26:in `block in <module:Sinatra>'
        4: from /store/gems/ruby-2.5.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1464:in `run!'
        3: from /store/gems/ruby-2.5.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1464:in `ensure in run!'
        2: from /store/gems/ruby-2.5.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1439:in `quit!'
        1: from /store/gems/ruby-2.5.0/gems/puma-3.12.0/lib/puma/launcher.rb:147:in `stop'
/store/gems/ruby-2.5.0/gems/puma-3.12.0/lib/puma/single.rb:27:in `stop': undefined method `stop' for nil:NilClass (NoMethodError)
Traceback (most recent call last):
        3: from /store/gems/ruby-2.5.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1545:in `block in setup_traps'
        2: from /store/gems/ruby-2.5.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1439:in `quit!'
        1: from /store/gems/ruby-2.5.0/gems/puma-3.12.0/lib/puma/launcher.rb:147:in `stop'
/store/gems/ruby-2.5.0/gems/puma-3.12.0/lib/puma/single.rb:27:in `stop': undefined method `stop' for nil:NilClass (NoMethodError)

由于我将其用作嵌入式服务器,所以我希望输出简单且存在Sinatra已经显示的友好错误:

== Someone is already performing on port 3000!

并避免显示回溯。

3 个答案:

答案 0 :(得分:1)

Ruby默认情况下将错误消息输出到STDOUT。但是,如果您使用的是* nix系统,则可以执行以下操作:

ruby test.rb > /dev/null 2>&1

对于Windows,您可能可以做到

ruby test.rb > NULL

windows powershell

ruby test.rb > $null

但对于Windows,也请参见Is there a /dev/null on Windows?

但是,如果要在服务器运行时以编程方式禁止输出,则应在* nix上运行,但不能在Windows上确定

# test.rb
require 'sinatra'
require 'bundler/inline'

gemfile do
  gem 'sinatra'
  gem 'puma'
end

set :bind, "0.0.0.0"
set :port, 3000

get '/' do
  "hello"
end

unless `ps aux | grep sinatra`.match('tcp://0.0.0.0:3000')
  STDOUT.reopen('/dev/null', 'w')
  STDERR.reopen('/dev/null', 'w')
end

请参见suppresing output to console with ruby

答案 1 :(得分:1)

您可以通过在允许Sinatra和Puma接管之前尝试监听端口来测试端口是否正在使用。这不是100%有效的,因为在某些竞争条件下,您可以打开和关闭端口,但是在Sinatra / Puma完成初始化之前,需要进行一些其他过程并在同一端口上进行侦听,但是它应该适合您的用例(似乎只是一个装饰性的技巧。

将此代码插入public HingeJoint doorHinge; public float rotatedoor = 0.0f; // Limit this value, min 0 max 120 void Update() { //Get the current the limit JointLimits limits = doorHinge.limits; //Set the limit to that copy limits.min = 0; limits.max = 120; limits.bounciness = 0; limits.bounceMinVelocity = 0; //Apply the limit since it's a struct doorHinge.limits = limits; JointSpring doorSpring = doorHinge.spring; doorSpring.targetPosition = rotatedoor; doorHinge.spring = doorSpring; } 中的任何位置:

test.rb

require 'socket' include Socket::Constants begin # Open and close the port socket = Socket.new(AF_INET, SOCK_STREAM, 0) sockaddr = Socket.pack_sockaddr_in(3000, '0.0.0.0') socket.bind(sockaddr) socket.listen(1) socket.close rescue Errno::EADDRINUSE => error # Traps the same error that is trapped by Sinatra and exits if raised puts error.message exit end 开始第一个:

ruby test.rb

== Sinatra (v2.0.4) has taken the stage on 3000 for development with backup from Puma Puma starting in single mode... * Version 3.12.0 (ruby 2.6.0-p-1), codename: Llamas in Pajamas * Min threads: 0, max threads: 16 * Environment: development * Listening on tcp://0.0.0.0:3000 Use Ctrl-C to stop 开始第二个:

ruby test.rb

您可以在Address already in use - bind(2) for 0.0.0.0:3000 块中将要打印的内容充实到控制台。

答案 2 :(得分:1)

这似乎是由issue with Puma修复的this PR引起的。