Beispiel #1
0
    def __call__(self, published, REQUEST, t, v, traceback):
        try:
            if t is SystemExit or issubclass(t, Redirect):
                raise t, v, traceback

            if issubclass(t, ConflictError):
                self.logConflicts(v, REQUEST)
                raise ZPublisher.Retry(t, v, traceback)

            if t is ZPublisher.Retry:
                try:
                    v.reraise()
                except:
                    # we catch the re-raised exception so that it gets
                    # stored in the error log and gets rendered with
                    # standard_error_message
                    t, v, traceback = sys.exc_info()
                if issubclass(t, ConflictError):
                    # ouch, a user saw this conflict error :-(
                    self.unresolved_conflict_errors += 1

            error_log_url = ''
            if not isinstance(published, list):
                try:
                    log = aq_acquire(published, '__error_log__', containment=1)
                except AttributeError:
                    pass
                else:
                    if log is not None:
                        error_log_url = log.raising((t, v, traceback))

            if (REQUEST is None or (getattr(REQUEST.get(
                    'RESPONSE', None), '_error_format', '') != 'text/html')):
                raise t, v, traceback

            # Lookup a view for the exception and render it, then
            # raise the rendered value as the exception value
            # (basically the same that 'raise_standardErrorMessage'
            # does. The view is named 'index.html' because that's what
            # zope.publisher uses as well.
            view = queryMultiAdapter((v, REQUEST), name=u'index.html')
            if view is not None:
                if IAcquirer.providedBy(view) and IAcquirer.providedBy(
                        published):
                    view = view.__of__(published)
                else:
                    view.__parent__ = published
                v = view()
                if issubclass(t, Unauthorized):
                    # Re-raise Unauthorized to make sure it is handled
                    # correctly. We can't do that with all exceptions
                    # because some don't work with the rendered v as
                    # argument.
                    raise t, v, traceback
                response = REQUEST.RESPONSE
                response.setStatus(t)
                response.setBody(v)
                return response

            if (published is None or published is app
                    or isinstance(published, list)):
                # At least get the top-level object
                published = app.__bobo_traverse__(REQUEST).__of__(
                    RequestContainer(REQUEST))

            published = getattr(published, 'im_self', published)
            while 1:
                f = getattr(published, self.raise_error_message, None)
                if f is None:
                    published = aq_parent(published)
                    if published is None:
                        raise t, v, traceback
                else:
                    break

            client = published
            while 1:
                if getattr(client, self.error_message, None) is not None:
                    break
                client = aq_parent(client)
                # If we are going in circles without getting the error_message
                # let the response handle it
                if client is None or aq_base(client) is aq_base(published):
                    response = REQUEST.RESPONSE
                    response.exception()
                    return response

            if REQUEST.get('AUTHENTICATED_USER', None) is None:
                REQUEST['AUTHENTICATED_USER'] = AccessControl.User.nobody

            result = f(client,
                       REQUEST,
                       t,
                       v,
                       traceback,
                       error_log_url=error_log_url)
            if result is not None:
                t, v, traceback = result
                if issubclass(t, Unauthorized):
                    # Re-raise Unauthorized to make sure it is handled
                    # correctly. We can't do that with all exceptions
                    # because some don't work with the rendered v as
                    # argument.
                    raise t, v, traceback
                response = REQUEST.RESPONSE
                response.setStatus(t)
                response.setBody(v)
                return response
        finally:
            traceback = None
Beispiel #2
0
def zpublisher_exception_hook(published, REQUEST, t, v, traceback):
    global unresolved_conflict_errors
    global conflict_errors
    try:
        if isinstance(t, StringType):
            if t.lower() in ('unauthorized', 'redirect'):
                raise
        else:
            if t is SystemExit:
                raise
            if issubclass(t, ConflictError):
                conflict_errors += 1
                level = getConfiguration().conflict_error_log_level
                if level:
                    conflict_logger.log(
                        level, "%s at %s: %s (%d conflicts (%d unresolved) "
                        "since startup at %s)", v.__class__.__name__,
                        REQUEST.get('PATH_INFO',
                                    '<unknown>'), v, conflict_errors,
                        unresolved_conflict_errors, startup_time)
                raise ZPublisher.Retry(t, v, traceback)
            if t is ZPublisher.Retry:
                try:
                    v.reraise()
                except:
                    # we catch the re-raised exception so that it gets
                    # stored in the error log and gets rendered with
                    # standard_error_message
                    t, v, traceback = sys.exc_info()
                if issubclass(t, ConflictError):
                    # ouch, a user saw this conflict error :-(
                    unresolved_conflict_errors += 1

        try:
            log = aq_acquire(published, '__error_log__', containment=1)
        except AttributeError:
            error_log_url = ''
        else:
            error_log_url = log.raising((t, v, traceback))

        if (getattr(REQUEST.get('RESPONSE', None), '_error_format', '') !=
                'text/html'):
            raise t, v, traceback

        if (published is None or published is app
                or type(published) is ListType):
            # At least get the top-level object
            published = app.__bobo_traverse__(REQUEST).__of__(
                RequestContainer(REQUEST))

        published = getattr(published, 'im_self', published)
        while 1:
            f = getattr(published, 'raise_standardErrorMessage', None)
            if f is None:
                published = getattr(published, 'aq_parent', None)
                if published is None:
                    raise t, v, traceback
            else:
                break

        client = published
        while 1:
            if getattr(client, 'standard_error_message', None) is not None:
                break
            client = getattr(client, 'aq_parent', None)
            if client is None:
                raise t, v, traceback

        if REQUEST.get('AUTHENTICATED_USER', None) is None:
            REQUEST['AUTHENTICATED_USER'] = AccessControl.User.nobody

        try:
            f(client, REQUEST, t, v, traceback, error_log_url=error_log_url)
        except TypeError:
            # Pre 2.6 call signature
            f(client, REQUEST, t, v, traceback)

    finally:
        traceback = None