AASM 状态机异常处理示例?
AASM state machine exception handling example?
我目前正在研究 class,它基本上是在做以下事情:
- 模型已创建
- 获取数据(事件"get_things!")
- 如果发生异常,状态应该变成"failed"
- 如果成功,状态应该是"finished"
我尝试按如下方式实现它:
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 - 但没有找到任何关于它的文档?
有什么想法吗?谢谢!
编辑: 更改了一些小部分以消除混淆。
首先,方法名是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
I would prefer something like the error handling which is mentioned in the readme
您的错误处理示例实际上是很好的做法(进行了一些小的修改):
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
我目前正在研究 class,它基本上是在做以下事情:
- 模型已创建
- 获取数据(事件"get_things!")
- 如果发生异常,状态应该变成"failed"
- 如果成功,状态应该是"finished"
我尝试按如下方式实现它:
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 - 但没有找到任何关于它的文档?
有什么想法吗?谢谢!
编辑: 更改了一些小部分以消除混淆。
首先,方法名是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
I would prefer something like the error handling which is mentioned in the readme
您的错误处理示例实际上是很好的做法(进行了一些小的修改):
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