AASM状态机异常处理示例?

时间:2017-05-24 11:53:07

标签: ruby-on-rails ruby-on-rails-3 state-machine aasm

我目前正在开设一个课程,基本上是在做以下几点:

  • 模型已创建
  • 获取数据(事件“get_things!”)
    • 如果发生异常,状态应该变为“失败”
    • 如果成功,州应该“完成”

我尝试按如下方式实现它:

class Fetcher < ActiveRecord::Base
  include AASM

  aasm do
    state :created, initial: true
    state :success, :failed

    event :succeed do
      transitions from: :created, to: :success
    end

    event :fail do
      transitions from: :created, to: :failed
    end
  end

  def read_things!(throw_exception = false)
    begin
      raise RuntimeError.new("RAISED EXCEPTION") if throw_exception
      self.content = open("https://example.com?asd=324").read
      self.succeed!
    rescue => e
      self.fail!
    end
  end
end

a = Fetcher.new
a.read_things!(throw_exception = true)
=> state should be failed

a = Fetcher.new
a.read_things!(throw_exception = false)
=> state should be succeess

它有效,但看起来不太好做......

我更喜欢自述文件中提到的错误处理之类的内容

event :read_things do
  before do
    self.content = open("https://example.com?asd=324").read
    self.succeed!
  end
  error do |e|
    self.fail!
  end
  transitions :from => :created, :to => :success
end

但我不知道这是否真的是最好的做法?

我也有很多事件,所有事情应该像我上面提到的错误处理一样,我看到我可以以某种方式使用error_on_all_events - 但是没有找到任何关于它的文档?

有什么想法?谢谢!

编辑:更改了一些小部件以消除混淆。

1 个答案:

答案 0 :(得分:1)

首先,方法名称是fetch!还是read_things?在任何情况下,您都不希望传递布尔参数来确定是否引发异常。如果出现异常,那么rescue会将其提取:

def read_things
  self.content = open("https://example.com?asd=324").read
  succeed!
rescue => e
  # do something with the error (e.g. log it), otherwise remove the "=> e"
  fail!
end
  

我更喜欢自述文件中提到的错误处理之类的内容

您的错误处理示例实际上是一种很好的做法(只需进行一些小编辑):

event :read_things do
  before do
    self.content = open("https://example.com?asd=324").read
  end
  error do |e|
    fail! # the self is optional (since self is your Fetcher object)
  end
  transitions from: :created, to: :success
end

在实践中:

a = Fetcher.new
a.read_things!

如果self.content未引发异常,则状态将从created过渡到success(无需直接调用succeed!),否则错误处理程序将调用fail!转换,尝试将状态转换为failed

修改

使用error_on_all_events进行AASM回调的示例:

aasm do
  error_on_all_events :handle_error_for_all_events

  state :created, initial: true
  state :success, :failed

  event :succeed do
    transitions from: :created, to: :success
  end

  event :fail do
    transitions from: :created, to: :failed
  end
end

def handle_error_for_all_events
  # inspect the aasm object and handle error...
  puts aasm
end