Exception handling
------------------

These tests capture the current behavior. Maybe some of that behavior should
be changed. The behavior caused by handleErrors=False shows only up in tests.


Create the browser object we'll be using.

    >>> from Products.Five.testbrowser import Browser
    >>> browser = Browser()
    >>> # XXX: browser has no API for disabling redirects
    >>> browser.mech_browser.set_handle_redirect(False)

Create the objects that are raising exceptions.
 
    >>> dummy = app.test_folder_1_._setObject('foo', ExceptionRaiser1())
    >>> dummy = app.test_folder_1_._setObject('bar', ExceptionRaiser2())
    >>> dummy = app.test_folder_1_._setObject('baz', ExceptionRaiser3())

Handle AttributeError.

    >>> app.test_folder_1_.foo.exception = AttributeError('ERROR VALUE')

    >>> browser.handleErrors = True
    >>> browser.open('http://localhost/test_folder_1_/foo')
    Traceback (most recent call last):
    ...
    HTTPError: HTTP Error 500: Internal Server Error
    >>> 'Error Type: AttributeError' in browser.contents
    True
    >>> 'Error Value: ERROR VALUE' in browser.contents
    True

    >>> browser.handleErrors = False
    >>> browser.open('http://localhost/test_folder_1_/foo')
    Traceback (most recent call last):
    ...
    AttributeError: ERROR VALUE

Handle ImportError.

    >>> app.test_folder_1_.foo.exception = ImportError('ERROR VALUE')

    >>> browser.handleErrors = True
    >>> browser.open('http://localhost/test_folder_1_/foo')
    Traceback (most recent call last):
    ...
    HTTPError: HTTP Error 500: Internal Server Error
    >>> 'Error Type: ImportError' in browser.contents
    True
    >>> 'Error Value: ERROR VALUE' in browser.contents
    True

    >>> browser.handleErrors = False
    >>> browser.open('http://localhost/test_folder_1_/foo')
    Traceback (most recent call last):
    ...
    ImportError: ERROR VALUE

Handle zope.publisher.interfaces.NotFound.

    >>> from zope.publisher.interfaces import NotFound
    >>> app.test_folder_1_.foo.exception = NotFound('OBJECT','NAME')

    >>> browser.handleErrors = True
    >>> browser.open('http://localhost/test_folder_1_/foo')
    Traceback (most recent call last):
    ...
    HTTPError: HTTP Error 404: Not Found
    >>> 'Error Type: NotFound' in browser.contents
    True
    >>> "Error Value: Object: 'OBJECT', name: 'NAME'" in browser.contents
    True

    >>> browser.handleErrors = False
    >>> browser.open('http://localhost/test_folder_1_/foo')
    Traceback (most recent call last):
    ...
    NotFound: Object: 'OBJECT', name: 'NAME'

Don't handle SystemExit, even if handleErrors is True.

    >>> app.test_folder_1_.foo.exception = SystemExit('ERROR VALUE')

    >>> browser.handleErrors = True
    >>> browser.open('http://localhost/test_folder_1_/foo')
    Traceback (most recent call last):
    ...
    SystemExit: ERROR VALUE

    >>> browser.handleErrors = False
    >>> browser.open('http://localhost/test_folder_1_/foo')
    Traceback (most recent call last):
    ...
    SystemExit: ERROR VALUE

Handle zExceptions.Redirect.

    >>> from zExceptions import Redirect
    >>> app.test_folder_1_.foo.exception = Redirect('LOCATION')

    >>> browser.handleErrors = True
    >>> browser.open('http://localhost/test_folder_1_/foo')
    Traceback (most recent call last):
    ...
    HTTPError: HTTP Error 302: Moved Temporarily
    >>> browser.contents
    ''
    >>> browser.headers['Location']
    'LOCATION'

    >>> browser.handleErrors = False
    >>> browser.open('http://localhost/test_folder_1_/foo')
    Traceback (most recent call last):
    ...
    Redirect: LOCATION

Handle zExceptions.Unauthorized raised by the object. We take the
'WWW-Authenticate' header as a sign that HTTPResponse._unauthorized was called.

    >>> from zExceptions import Unauthorized
    >>> app.test_folder_1_.foo.exception = Unauthorized('ERROR VALUE')

    >>> browser.handleErrors = True
    >>> browser.open('http://localhost/test_folder_1_/foo')
    Traceback (most recent call last):
    ...
    HTTPError: HTTP Error 401: Unauthorized
    >>> 'Error Type: Unauthorized' in browser.contents
    True
    >>> 'Error Value: ERROR VALUE' in browser.contents
    True
    >>> browser.headers['WWW-Authenticate']
    'basic realm="Zope2"'

    >>> browser.handleErrors = False
    >>> browser.open('http://localhost/test_folder_1_/foo')
    Traceback (most recent call last):
    ...
    Unauthorized: ERROR VALUE

And the same with unicode error value.

    >>> app.test_folder_1_.foo.exception = Unauthorized(u'ERROR VALUE \u03A9')

    >>> browser.handleErrors = True
    >>> browser.open('http://localhost/test_folder_1_/foo')
    Traceback (most recent call last):
    ...
    HTTPError: HTTP Error 401: Unauthorized
    >>> 'Error Type: Unauthorized' in browser.contents
    True
    >>> 'Error Value: ERROR VALUE ?' in browser.contents
    True
    >>> browser.headers['WWW-Authenticate']
    'basic realm="Zope2"'

    >>> browser.handleErrors = False
    >>> browser.open('http://localhost/test_folder_1_/foo')
    Traceback (most recent call last):
    ...
    Unauthorized: ...

Handle zExceptions.Unauthorized raised by BaseRequest.traverse. We take the
'WWW-Authenticate' header as a sign that HTTPResponse._unauthorized was called.

    >>> browser.handleErrors = True
    >>> browser.open('http://localhost/test_folder_1_/bar')
    Traceback (most recent call last):
    ...
    HTTPError: HTTP Error 401: Unauthorized
    >>> 'Site Error' in browser.contents
    True
    >>> 'You are not authorized to access this resource.' in browser.contents
    True
    >>> browser.headers['WWW-Authenticate']
    'basic realm="Zope2"'

    >>> browser.handleErrors = False
    >>> browser.open('http://localhost/test_folder_1_/bar')
    Traceback (most recent call last):
    ...
    Unauthorized: <strong>You are not authorized to access this resource...

Handle zExceptions.Forbidden raised by BaseRequest.traverse. 'traverse'
converts it into zExceptions.NotFound if we are not in debug mode.

    >>> browser.handleErrors = True
    >>> browser.open('http://localhost/test_folder_1_/baz')
    Traceback (most recent call last):
    ...
    HTTPError: HTTP Error 404: Not Found
    >>> '&lt;p&gt;&lt;strong&gt;Resource not found&lt;/strong&gt;&lt;/p&gt;' in browser.contents
    True
    >>> '&lt;p&gt;&lt;b&gt;Resource:&lt;/b&gt; index_html&lt;/p&gt;' in browser.contents
    True

    >>> browser.handleErrors = False
    >>> browser.open('http://localhost/test_folder_1_/baz')
    Traceback (most recent call last):
    ...
    NotFound:   <h2>Site Error</h2>
    ...<p><strong>Resource not found</strong></p>...
    ...<p><b>Resource:</b> index_html</p>...
