Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
张重言
rails
提交
259a7a84
R
rails
项目概览
张重言
/
rails
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rails
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
259a7a84
编写于
10月 04, 2008
作者:
P
Pratik Naik
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add tests for ActiveSupport::Rescuable. Use ActiveSupport::Rescuable in ActionController::Base.
上级
964dfc15
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
136 addition
and
119 deletion
+136
-119
actionpack/lib/action_controller/rescue.rb
actionpack/lib/action_controller/rescue.rb
+3
-99
activesupport/CHANGELOG
activesupport/CHANGELOG
+2
-0
activesupport/lib/active_support.rb
activesupport/lib/active_support.rb
+2
-0
activesupport/lib/active_support/rescuable.rb
activesupport/lib/active_support/rescuable.rb
+54
-20
activesupport/test/rescuable_test.rb
activesupport/test/rescuable_test.rb
+75
-0
未找到文件。
actionpack/lib/action_controller/rescue.rb
浏览文件 @
259a7a84
...
...
@@ -41,10 +41,9 @@ def self.included(base) #:nodoc:
base
.
rescue_templates
=
Hash
.
new
(
DEFAULT_RESCUE_TEMPLATE
)
base
.
rescue_templates
.
update
DEFAULT_RESCUE_TEMPLATES
base
.
class_inheritable_array
:rescue_handlers
base
.
rescue_handlers
=
[]
base
.
extend
(
ClassMethods
)
base
.
send
:include
,
ActiveSupport
::
Rescuable
base
.
class_eval
do
alias_method_chain
:perform_action
,
:rescue
end
...
...
@@ -54,65 +53,12 @@ module ClassMethods
def
process_with_exception
(
request
,
response
,
exception
)
#:nodoc:
new
.
process
(
request
,
response
,
:rescue_action
,
exception
)
end
# Rescue exceptions raised in controller actions.
#
# <tt>rescue_from</tt> receives a series of exception classes or class
# names, and a trailing <tt>:with</tt> option with the name of a method
# or a Proc object to be called to handle them. Alternatively a block can
# be given.
#
# Handlers that take one argument will be called with the exception, so
# that the exception can be inspected when dealing with it.
#
# Handlers are inherited. They are searched from right to left, from
# bottom to top, and up the hierarchy. The handler of the first class for
# which <tt>exception.is_a?(klass)</tt> holds true is the one invoked, if
# any.
#
# class ApplicationController < ActionController::Base
# rescue_from User::NotAuthorized, :with => :deny_access # self defined exception
# rescue_from ActiveRecord::RecordInvalid, :with => :show_errors
#
# rescue_from 'MyAppError::Base' do |exception|
# render :xml => exception, :status => 500
# end
#
# protected
# def deny_access
# ...
# end
#
# def show_errors(exception)
# exception.record.new_record? ? ...
# end
# end
def
rescue_from
(
*
klasses
,
&
block
)
options
=
klasses
.
extract_options!
unless
options
.
has_key?
(
:with
)
block_given?
?
options
[
:with
]
=
block
:
raise
(
ArgumentError
,
"Need a handler. Supply an options hash that has a :with key as the last argument."
)
end
klasses
.
each
do
|
klass
|
key
=
if
klass
.
is_a?
(
Class
)
&&
klass
<=
Exception
klass
.
name
elsif
klass
.
is_a?
(
String
)
klass
else
raise
(
ArgumentError
,
"
#{
klass
}
is neither an Exception nor a String"
)
end
# Order is important, we put the pair at the end. When dealing with an
# exception we will follow the documented order going from right to left.
rescue_handlers
<<
[
key
,
options
[
:with
]]
end
end
end
protected
# Exception handler called when the performance of an action raises an exception.
def
rescue_action
(
exception
)
rescue_
action_
with_handler
(
exception
)
||
rescue_action_without_handler
(
exception
)
rescue_with_handler
(
exception
)
||
rescue_action_without_handler
(
exception
)
end
# Overwrite to implement custom logging of errors. By default logs as fatal.
...
...
@@ -168,18 +114,6 @@ def rescue_action_locally(exception)
render_for_file
(
rescues_path
(
"layout"
),
response_code_for_rescue
(
exception
))
end
# Tries to rescue the exception by looking up and calling a registered handler.
def
rescue_action_with_handler
(
exception
)
if
handler
=
handler_for_rescue
(
exception
)
if
handler
.
arity
!=
0
handler
.
call
(
exception
)
else
handler
.
call
end
true
# don't rely on the return value of the handler
end
end
def
rescue_action_without_handler
(
exception
)
log_error
(
exception
)
if
logger
erase_results
if
performed?
...
...
@@ -216,36 +150,6 @@ def response_code_for_rescue(exception)
rescue_responses
[
exception
.
class
.
name
]
end
def
handler_for_rescue
(
exception
)
# We go from right to left because pairs are pushed onto rescue_handlers
# as rescue_from declarations are found.
_
,
handler
=
*
rescue_handlers
.
reverse
.
detect
do
|
klass_name
,
handler
|
# The purpose of allowing strings in rescue_from is to support the
# declaration of handler associations for exception classes whose
# definition is yet unknown.
#
# Since this loop needs the constants it would be inconsistent to
# assume they should exist at this point. An early raised exception
# could trigger some other handler and the array could include
# precisely a string whose corresponding constant has not yet been
# seen. This is why we are tolerant to unknown constants.
#
# Note that this tolerance only matters if the exception was given as
# a string, otherwise a NameError will be raised by the interpreter
# itself when rescue_from CONSTANT is executed.
klass
=
self
.
class
.
const_get
(
klass_name
)
rescue
nil
klass
||=
klass_name
.
constantize
rescue
nil
exception
.
is_a?
(
klass
)
if
klass
end
case
handler
when
Symbol
method
(
handler
)
when
Proc
handler
.
bind
(
self
)
end
end
def
clean_backtrace
(
exception
)
if
backtrace
=
exception
.
backtrace
if
defined?
(
RAILS_ROOT
)
...
...
activesupport/CHANGELOG
浏览文件 @
259a7a84
*Edge*
* Add ActiveSupport::Rescuable module abstracting ActionController::Base rescue_from features. [Norbert Crombach, Pratik]
* Switch from String#chars to String#mb_chars for the unicode proxy. [Manfred Stienstra]
This helps with 1.8.7 compatibility and also improves performance for some operations by reducing indirection.
...
...
activesupport/lib/active_support.rb
浏览文件 @
259a7a84
...
...
@@ -56,6 +56,8 @@
require
'active_support/secure_random'
require
'active_support/rescuable'
I18n
.
load_path
<<
File
.
dirname
(
__FILE__
)
+
'/active_support/locale/en-US.yml'
Inflector
=
ActiveSupport
::
Deprecation
::
DeprecatedConstantProxy
.
new
(
'Inflector'
,
'ActiveSupport::Inflector'
)
...
...
activesupport/lib/active_support/rescuable.rb
浏览文件 @
259a7a84
module
ActiveSupport
# Rescuable module adds support for easier exception handling.
module
Rescuable
def
self
.
included
(
base
)
# :nodoc:
base
.
class_inheritable_a
rray
:rescue_handlers
base
.
class_inheritable_a
ccessor
:rescue_handlers
base
.
rescue_handlers
=
[]
base
.
extend
(
ClassMethods
)
end
module
ClassMethods
def
enable_rescue_for
(
*
methods
)
methods
.
each
do
|
method
|
class_eval
<<-
EOS
def
#{
method
}
_with_rescue(*args, &block)
#{
method
}
_without_rescue(*args, &block)
rescue Exception => exception
rescue_with_handler(exception)
end
alias_method_chain :
#{
method
}
, :rescue
EOS
end
end
# Rescue exceptions raised in controller actions.
#
# <tt>rescue_from</tt> receives a series of exception classes or class
# names, and a trailing <tt>:with</tt> option with the name of a method
# or a Proc object to be called to handle them. Alternatively a block can
# be given.
#
# Handlers that take one argument will be called with the exception, so
# that the exception can be inspected when dealing with it.
#
# Handlers are inherited. They are searched from right to left, from
# bottom to top, and up the hierarchy. The handler of the first class for
# which <tt>exception.is_a?(klass)</tt> holds true is the one invoked, if
# any.
#
# class ApplicationController < ActionController::Base
# rescue_from User::NotAuthorized, :with => :deny_access # self defined exception
# rescue_from ActiveRecord::RecordInvalid, :with => :show_errors
#
# rescue_from 'MyAppError::Base' do |exception|
# render :xml => exception, :status => 500
# end
#
# protected
# def deny_access
# ...
# end
#
# def show_errors(exception)
# exception.record.new_record? ? ...
# end
# end
def
rescue_from
(
*
klasses
,
&
block
)
options
=
klasses
.
extract_options!
unless
options
.
has_key?
(
:with
)
if
block_given?
options
[
:with
]
=
block
...
...
@@ -46,18 +67,31 @@ def rescue_from(*klasses, &block)
end
end
# Tries to rescue the exception by looking up and calling a registered handler.
def
rescue_with_handler
(
exception
)
if
handler
=
handler_for_rescue
(
exception
)
handler
.
arity
!=
0
?
handler
.
call
(
exception
)
:
handler
.
call
else
raise
exception
true
# don't rely on the return value of the handler
end
end
def
handler_for_rescue
(
exception
)
# use reverse so what is added last is found first
_
,
handler
=
*
rescue_handlers
.
reverse
.
detect
do
|
klass_name
,
handler
|
# allow strings to support constants that are not defined yet
# We go from right to left because pairs are pushed onto rescue_handlers
# as rescue_from declarations are found.
_
,
handler
=
Array
(
rescue_handlers
).
reverse
.
detect
do
|
klass_name
,
handler
|
# The purpose of allowing strings in rescue_from is to support the
# declaration of handler associations for exception classes whose
# definition is yet unknown.
#
# Since this loop needs the constants it would be inconsistent to
# assume they should exist at this point. An early raised exception
# could trigger some other handler and the array could include
# precisely a string whose corresponding constant has not yet been
# seen. This is why we are tolerant to unknown constants.
#
# Note that this tolerance only matters if the exception was given as
# a string, otherwise a NameError will be raised by the interpreter
# itself when rescue_from CONSTANT is executed.
klass
=
self
.
class
.
const_get
(
klass_name
)
rescue
nil
klass
||=
klass_name
.
constantize
rescue
nil
exception
.
is_a?
(
klass
)
if
klass
...
...
activesupport/test/rescuable_test.rb
0 → 100644
浏览文件 @
259a7a84
require
'abstract_unit'
class
WraithAttack
<
StandardError
end
class
NuclearExplosion
<
StandardError
end
class
MadRonon
<
StandardError
attr_accessor
:message
def
initialize
(
message
)
@message
=
message
super
()
end
end
class
Stargate
attr_accessor
:result
include
ActiveSupport
::
Rescuable
rescue_from
WraithAttack
,
:with
=>
:sos
rescue_from
NuclearExplosion
do
@result
=
'alldead'
end
rescue_from
MadRonon
do
|
e
|
@result
=
e
.
message
end
def
dispatch
(
method
)
send
(
method
)
rescue
Exception
=>
e
rescue_with_handler
(
e
)
end
def
attack
raise
WraithAttack
end
def
nuke
raise
NuclearExplosion
end
def
ronanize
raise
MadRonon
.
new
(
"dex"
)
end
def
sos
@result
=
'killed'
end
end
class
RescueableTest
<
Test
::
Unit
::
TestCase
def
setup
@stargate
=
Stargate
.
new
end
def
test_rescue_from_with_method
@stargate
.
dispatch
:attack
assert_equal
'killed'
,
@stargate
.
result
end
def
test_rescue_from_with_block
@stargate
.
dispatch
:nuke
assert_equal
'alldead'
,
@stargate
.
result
end
def
test_rescue_from_with_block_with_args
@stargate
.
dispatch
:ronanize
assert_equal
'dex'
,
@stargate
.
result
end
end
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录