什么类型的错误应该使用Ruby的Exception类,其他的处理策略是什么?

ctehm74n  于 2023-06-22  发布在  Ruby
关注(0)|答案(1)|浏览(151)

上下文是我正在构建的一个CLI国际象棋游戏项目,它处理诸如用户输入格式错误之类的条件,并根据各种游戏和棋子规则验证国际象棋的移动。我正在寻求最合适的技术来处理这类情况/条件/错误的指导-使用Exception类,编写自己的救援方法和/或任何其他方法。
例如,在下面的方法中,我写了一个自定义的'case/condition handler'类型的方法,它只是向用户发送一条关于问题的消息,然后再次尝试代码,有效地循环,直到用户输入正确的格式,就像这样:
游戏#get_move & #rescue_invalid_format_error:

def get_move
  ...
  return rescue_invalid_format_error(move) unless chess_format?(move)
  ...
end

def rescue_invalid_format_error(move)
   puts "your move; '#{move}' was not formatted correctly, it should be formatted like; 'a1,a2', try again..."
   get_move
end

然后在其他代码中,我最终构建了自定义的Exception类,如下所示:
input_errors.rb:

class InputError < StandardError
  def initialize(message = 'Input error')
    super(message)
  end
end

并且在'错误'情况下引发Exception对象,例如:

def add_move(indexed_move)
    if index_format?(indexed_move)
      true_move?(indexed_move) ? @moves << indexed_move : (raise InputError.new("Input; #{indexed_move} does not represent an actual move"))
    else
      raise InputError.new("Indexed_move; #{indexed_move} should be formatted like 'iiii'")
    end
  end
  • (尽管我没有用begin rescue块 Package 任何调用上述#add_move的代码,因为我认为InputError已经在处理异常了,在它的祖先代码中的某个地方(尽管我不确定))。

所以,我的问题的实质是;在Ruby中,用什么样的错误处理方法/策略来处理什么样的条件,正确的方法是什么?
先谢谢你了。

xvw2m8pv

xvw2m8pv1#

在软件设计中没有使用异常的“正确方法”。例如,即使是流行的Ruby style guide也基本上忽略了这个问题。它最强烈的建议是不要在控制流中使用异常,这在所有现代编程语言中都被广泛接受。
话虽如此,这里是我使用的准则(Ruby以及其他语言)。

对库中的复杂错误使用异常

如果您正在开发一个希望在多个应用程序中重用的gem,那么异常可能是从库中返回信息丰富的错误的好方法。例如,这种风格在Ruby的几个标准部分中使用,例如File类。
但要小心:你的库应该假设这些异常可能会被捕获,所以当这种情况发生时,它应该让自己处于某种合理的状态。你不想抛出一个漂亮的自定义异常,只是为了让它被捕获,现在你的库处于某种意想不到的状态,调用者在任何时候试图做任何事情时都会得到一个不漂亮的RuntimeError
使用异常的一个例外:如果库错误状态非常简单,则抛出自定义异常没有多大好处。主要的好处是在自定义类型和消息中传递的信息。因此,如果您不需要它,可以考虑简单地返回nil来指示错误。

在应用中使用异常来处理 * 真正的异常 * 情况

如果你正在构建一个面向用户的应用程序(包括CLI),在代码中为那些不应该发生的情况保留异常,但从技术上讲,它可能会例如,你有一个数组索引,它应该总是有效的,但不知何故数组太小,一个变量应该已经初始化,但不知何故它仍然是nil,诸如此类的东西。
换个说法:只在你不想捕捉的情况下使用异常,异常更多的是一种向你展示你的假设是错误的方式,这样你就可以修复错误。这种用法的一个好处是,你通常可以在Ruby中免费获得它,而不需要任何自定义代码,例如,你得到NoMethodError,它会告诉你到底出了什么问题。通常,您唯一希望捕获此类异常的地方是整个应用程序周围的一些高级begin rescue,用于用“Sorry,something went wrong”消息来修饰它。
特别是,从用户处获得输入并且该输入是无效的是完全不例外的。用户总是这样做。通常在我的CLI应用程序中,我会添加一个helper函数,它为用户提供提示,解释输入应该是什么样子,它在内部循环,直到他们输入正确的东西。这样的方法不需要任何方式来表示错误,因为它要么返回有效输入,要么根本不返回。

一般情况下,优先选择已有的异常类型

在声明自定义异常类之前,请仔细检查existing exception types是否适合您的情况。

相关问题