рубиновый камень мешает мне спасти - PullRequest
0 голосов
/ 07 июня 2018

Я пытаюсь создать бота Discord, выполнив вход в систему непосредственно на сервере Discord, на котором он находится, однако сам гем Discordrb отказывается позволить мне спасти сам блок.

begin
require 'discordrb'
phoenix = Discordrb::Bot.new token: 'TOKEN'
crashpass = rand(0..9999999)
puts "Crash password: #{crashpass}" #Prints to the terminal screen, not to the server
phoenix.message(with_text: "CP!crash #{crashpass}") do
        raise "Admin initiated crash."
end
rescue Exception #I know, bad practice, but I wish for this to always execute on error.
ensure
    phoenix.run :async #allows code to keep running after bot initialization
    phoenix.dnd
    phoenix.send_message(454137675944034314, "Something terrible has happened, and I can't recover!\n#{e}")
    phoenix.send_message(454137675944034314, "Currently running in emergency mode!")
    phoenix.sync
end

Это приводит кэто:

Using WSCS version: 0.3.0
libsodium not available! You can continue to use discordrb as normal but voice support won't work.
        Read https://github.com/meew0/discordrb/wiki/Installing-libsodium for more details.
Crash password: 6736731
[INFO : websocket @ 2018-06-07 19:04:57.517] Discord using gateway protocol version: 6, requested: 6
[ERROR : et-1 @ 2018-06-07 19:05:33.326] Exception: #<RuntimeError: Admin initiated crash.>
[ERROR : et-1 @ 2018-06-07 19:05:33.330] C:/Users/nathan/Desktop/Cyan_Phoenix local/bot.rb:19:in `block in <main>'
[ERROR : et-1 @ 2018-06-07 19:05:33.330] C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/discordrb-3.2.1/lib/discordrb/events/generic.rb:98:in `call'
[ERROR : et-1 @ 2018-06-07 19:05:33.330] C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/discordrb-3.2.1/lib/discordrb/bot.rb:1227:in `block in call_event'

Бот не останавливает и не сообщает об ошибке на сервер, игнорируя все спасение, включая обеспечение (которое, я считаю, гарантированно по крайней мере начнет работать).

Есть ли способ заставить скрипт обрабатывать мои ошибки вместо встроенных в гемы?

1 Ответ

0 голосов
/ 07 июня 2018

Это только помешает вам спасать исключения внутри phoenix.

require 'discordrb'
phoenix = Discordrb::Bot.new token: 'TOKEN'
phoenix.run :async
begin
  raise "Error here!"
rescue Exception
  puts "Got exception!"
end

Что-то вроде этого будет работать нормально, но когда вы делаете что-то вроде:

phoenix.message(with_text: "CP!crash #{crashpass}") do
  raise "Admin initiated crash."
end

Исключение будет сгенерировано внутри асинхронно работающего экземпляра phoenix DiscorrRb::Bot, который имеет свою собственную обработку ошибок, так что исключения, возникающие при работе в фоновом режиме, такие как переподключение после любых ошибок подключения, будут обрабатываться вместосбой остальной части приложения.

Если вы хотите отправить сообщения об исключениях на дискорд, вам нужно будет изменить Discordrb::Logger.Однако я не думаю, что это очень полезно, так как, скорее всего, исключения, возникшие внутри асинхронного кода Discordrb::Bot, будут связаны с ситуацией, когда соединение перестало работать, и оно не сможет отправить сообщение об исключении.к разногласиям, вызывая бесконечное переполнение цикла / стека, когда отправка сообщения об исключении для разногласий вызывает исключение, потому что разорванное соединение разорвано.

Если, однако, вы хотите какие-либо исключения в вашем коде (не Discordrb::Bot 's код) ничто не мешает вам написать что-то вроде:

phoenix.run :async

loop do
  begin
    score = calculate_score
    phoenix.send_message(channel_id, "Score : #{score}")
  rescue => ex
    phoenix.send_message(
      channel_id,
      "crash while calulcating score! #{ex.class} : #{ex.message}"
    )
    sleep 10
    retry
  end
  sleep 10
end

И если вы хотите спасти внутри обработчика событий:

phoenix.message(with_text: "score?") do |event|
  begin
    score = ScoreCalc.calculate_score
    event.respond("Score : #{score}")
  rescue => ex
     send_message(454137675944034314, "CRASHED! #{ex.class}: #{ex.message}")
     send_message(454137675944034314, ex.backtrace.join("\n"))
     event.respond "Sorry, there was a problem and it has been reported"
  end
end

Обработка исключений в поточном / асинхронном коде - этоРаспространенная проблема в Ruby.

...