doc(API): Document the order in which error handlers are visited (#846)
Document and add tests to confirm the LIFO order that error handlers are visited when handling an exception.
This commit is contained in:
committed by
Fran Fitzpatrick
parent
5040782f50
commit
fd5a0ba587
@@ -375,6 +375,18 @@ class API(object):
|
||||
def add_error_handler(self, exception, handler=None):
|
||||
"""Registers a handler for a given exception error type.
|
||||
|
||||
A handler can either raise an instance of ``HTTPError``
|
||||
or modify `resp` manually in order to communicate
|
||||
information about the issue to the client.
|
||||
|
||||
Error handlers are matched in LIFO order. In other words, when
|
||||
searching for an error handler to match a raised exception, and
|
||||
more than one handler matches the exception type, the framework
|
||||
will choose the one that was most recently registered.
|
||||
Therefore, more general error handlers (e.g., for the
|
||||
``Exception`` type) should be added first, to avoid masking more
|
||||
specific handlers for subclassed types.
|
||||
|
||||
Args:
|
||||
exception (type): Whenever an error occurs when handling a request
|
||||
that is an instance of this exception class, the associated
|
||||
@@ -396,10 +408,6 @@ class API(object):
|
||||
# Convert to an instance of falcon.HTTPError
|
||||
raise falcon.HTTPError(falcon.HTTP_792)
|
||||
|
||||
Note:
|
||||
A handler can either raise an instance of ``HTTPError``
|
||||
or modify `resp` manually in order to communicate
|
||||
information about the issue to the client.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
@@ -81,9 +81,29 @@ class TestErrorHandler(testing.TestCase):
|
||||
self.assertEqual(result.status_code, 723)
|
||||
self.assertEqual(result.text, 'error: CustomException')
|
||||
|
||||
def test_error_order(self):
|
||||
def test_error_order_duplicate(self):
|
||||
self.api.add_error_handler(Exception, capture_error)
|
||||
self.api.add_error_handler(Exception, handle_error_first)
|
||||
|
||||
result = self.simulate_get()
|
||||
self.assertEqual(result.text, 'first error handler')
|
||||
|
||||
def test_error_order_subclass(self):
|
||||
self.api.add_error_handler(Exception, capture_error)
|
||||
self.api.add_error_handler(CustomException, handle_error_first)
|
||||
|
||||
result = self.simulate_delete()
|
||||
self.assertEqual(result.status_code, 200)
|
||||
self.assertEqual(result.text, 'first error handler')
|
||||
|
||||
result = self.simulate_get()
|
||||
self.assertEqual(result.status_code, 723)
|
||||
self.assertEqual(result.text, 'error: Plain Exception')
|
||||
|
||||
def test_error_order_subclass_masked(self):
|
||||
self.api.add_error_handler(CustomException, handle_error_first)
|
||||
self.api.add_error_handler(Exception, capture_error)
|
||||
|
||||
result = self.simulate_delete()
|
||||
self.assertEqual(result.status_code, 723)
|
||||
self.assertEqual(result.text, 'error: CustomException')
|
||||
|
||||
Reference in New Issue
Block a user