2

我目前正在上课,基本上是在做以下事情:

  • 模型被创建
  • 获取数据(事件“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 - 但没有找到任何关于它的文档?

有什么想法吗?谢谢!

编辑:更改了一些小部分以消除混乱。

4

1 回答 1

2

First, is the method name fetch! or read_things? In any case, you don't want to pass a boolean argument to determine whether or not to raise an exception. If an exception is raised then your rescue will pick it up:

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

I would prefer something like the error handling which is mentioned in the readme

Your error handling example is actually good practice (with a few minor edits):

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

In practice:

a = Fetcher.new
a.read_things!

If self.content doesn't raise an exception then the state will transition from created to success (no need to call succeed! directly), otherwise the error handler will call the fail! transition, which will attempt to transition the state to failed.

EDIT:

Example usage of error_on_all_events callback with 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
于 2017-05-24T13:09:30.017 回答