繁体   English   中英

如何在未安装gem时从require“gem_name”进行救援

[英]How to rescue from a require “gem_name” when the gem is not installed

我正在写一个依赖于特定宝石的库。 我需要宝石并在我的代码中使用它,只要宝石安装在用户的机器上,所有东西都是hunky-dory。 但如果不是这样呢?!

我认为这很好,因为我可以从require命令中解救并向输出打印一条消息,告知用户缺少的宝石并优雅地完成它但我收到错误!

你能告诉我应该怎么做或这段代码有什么问题:

begin 
 require "some_gem"
rescue
 puts "please install some_gem first!" 
end

require引起了LoadError异常,如果它不能加载所需的库。 但是,您永远不会LoadError抢救,您可以从StandardError解救出来。

如果你想从LoadError ,你必须这样说:

begin 
  require 'some_gem'
rescue LoadError
  puts 'please install some_gem first!'
end

更好的是,确保您实际上正在打印正确的缺失依赖项:

begin 
  require 'some_gem'
rescue LoadError => e
  raise unless e.message =~ /some_gem/
  puts 'please install some_gem first!'
end

(这会重新引发从中获取的完全相同的异常,如果异常实际上是由其他地方的其他一些丢失的库引起的。你不想打印误导信息,对吗?)

根据库的预期目标受众是什么以及它们是否可能被转储到控制台的回溯吓跑,您可能想要在任何情况下重新引发异常,而不是仅仅吞下它:

begin 
  require 'some_gem'
rescue LoadError => e
  puts 'please install some_gem first!' if e.message =~ /some_gem/
  raise
end

或者,您可以跳过puts ,而是将消息设置为您想要的内容而引发异常:

begin 
  require 'some_gem'
rescue LoadError => e
  raise e.exception('please install some_gem first!') if e.message =~ /some_gem/
  raise
end

除非现在异常在错误的位置引发,因此具有错误的行号和堆栈跟踪,因此具有误导性,但这很容易修复:

begin 
  require 'some_gem'
rescue LoadError => e
  raise unless e.message =~ /some_gem/
  friendly_ex = e.exception('please install some_gem first!')
  friendly_ex.set_backtrace(e.backtrace)
  raise friendly_ex
end

现在你打印几乎与使用puts打印的东西相同, 你有一个“正确的”例外,例如允许更好的调试或允许你的库的消费者拯救那个异常并按照他们的方式处理它们,对于那些只是吞下异常的解决方案来说,这是不可能的,或者至少是难以实现的。

begin
  require "some_gem"
rescue LoadError
  puts "message"
end

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM