mirror of
https://github.com/reddit-archive/reddit.git
synced 2026-04-27 03:00:12 -04:00
Replace abort() to pass exception info to error pages.
This commit is contained in:
@@ -69,6 +69,11 @@ def error_mapper(code, message, environ, global_conf=None, **kw):
|
||||
if code in codes:
|
||||
# StatusBasedForward expects a relative URL (no SCRIPT_NAME)
|
||||
d = dict(code = code, message = message)
|
||||
|
||||
exception = environ.get('r2.controller.exception')
|
||||
if exception:
|
||||
d['explanation'] = exception.explanation
|
||||
|
||||
if environ.get('REDDIT_CNAME'):
|
||||
d['cnameframe'] = 1
|
||||
if environ.get('REDDIT_NAME'):
|
||||
|
||||
@@ -116,7 +116,8 @@ class ErrorController(RedditController):
|
||||
else:
|
||||
res = pages.RedditError(
|
||||
title=_("forbidden (%(domain)s)") % dict(domain=g.domain),
|
||||
message=_("you are not allowed to do that"))
|
||||
message=_("you are not allowed to do that"),
|
||||
explanation=request.GET.get('explanation'))
|
||||
return res.render()
|
||||
|
||||
def send404(self):
|
||||
|
||||
@@ -20,12 +20,14 @@
|
||||
# Inc. All Rights Reserved.
|
||||
###############################################################################
|
||||
|
||||
from paste.httpexceptions import HTTPForbidden
|
||||
from r2.lib.utils import Storage, tup
|
||||
from pylons.i18n import _
|
||||
from copy import copy
|
||||
|
||||
error_list = dict((
|
||||
('USER_REQUIRED', _("please login to do that")),
|
||||
('HTTPS_REQUIRED', _("this page must be accessed using https")),
|
||||
('VERIFIED_USER_REQUIRED', _("you need to set a valid email address to do that.")),
|
||||
('NO_URL', _('a url is required')),
|
||||
('BAD_URL', _('you should check that url')),
|
||||
@@ -161,6 +163,11 @@ class ErrorSet(object):
|
||||
if self.errors.has_key(pair):
|
||||
del self.errors[pair]
|
||||
|
||||
class ForbiddenError(HTTPForbidden):
|
||||
def __init__(self, error):
|
||||
HTTPForbidden.__init__(self)
|
||||
self.explanation = error_list[error]
|
||||
|
||||
class UserRequiredException(Exception): pass
|
||||
class VerifiedUserRequiredException(Exception): pass
|
||||
class GoldRequiredException(Exception): pass
|
||||
|
||||
@@ -22,10 +22,9 @@
|
||||
|
||||
from mako.filters import url_escape
|
||||
from pylons import c, g, request
|
||||
from pylons.controllers.util import abort, redirect_to
|
||||
from pylons.controllers.util import redirect_to
|
||||
from pylons.i18n import _
|
||||
from pylons.i18n.translation import LanguageError
|
||||
from r2.lib.base import BaseController, proxyurl
|
||||
from r2.lib import pages, utils, filters, amqp, stats
|
||||
from r2.lib.utils import http_utils, is_subdomain, UniqueIterator, is_throttled
|
||||
from r2.lib.cache import LocalCache, make_key, MemcachedError
|
||||
@@ -33,11 +32,13 @@ import random as rand
|
||||
from r2.models.account import valid_cookie, FakeAccount, valid_feed, valid_admin_cookie
|
||||
from r2.models.subreddit import Subreddit, Frontpage
|
||||
from r2.models import *
|
||||
from errors import ErrorSet
|
||||
from errors import ErrorSet, ForbiddenError, errors
|
||||
from validator import *
|
||||
from r2.lib.template_helpers import add_sr
|
||||
from r2.config.extensions import is_api
|
||||
from r2.lib.translation import set_lang
|
||||
from r2.lib.contrib import ipaddress
|
||||
from r2.lib.base import BaseController, proxyurl, abort
|
||||
|
||||
from Cookie import CookieError
|
||||
from copy import copy
|
||||
@@ -544,7 +545,7 @@ def cross_domain(origin_check=is_trusted_origin, **options):
|
||||
|
||||
def require_https():
|
||||
if not c.secure:
|
||||
abort(403)
|
||||
abort(ForbiddenError(errors.HTTPS_REQUIRED))
|
||||
|
||||
def prevent_framing_and_css(allow_cname_frame=False):
|
||||
def wrap(f):
|
||||
|
||||
@@ -26,8 +26,8 @@ import sqlalchemy.exc
|
||||
|
||||
from pylons import Response, c, g, request, session, config
|
||||
from pylons.controllers import WSGIController, Controller
|
||||
from pylons.controllers.util import abort
|
||||
from pylons.i18n import N_, _, ungettext, get_lang
|
||||
from paste import httpexceptions
|
||||
from r2.lib.utils import to_js
|
||||
from r2.lib.filters import spaceCompress, _force_unicode
|
||||
from r2.lib.template_helpers import get_domain
|
||||
@@ -63,6 +63,22 @@ def is_local_address(ip):
|
||||
# TODO: support the /20 and /24 private networks? make this configurable?
|
||||
return ip.startswith('10.')
|
||||
|
||||
def abort(code_or_exception=None, detail="", headers=None, comment=None):
|
||||
"""Raise an HTTPException and save it in environ for use by error pages."""
|
||||
# Pylons 0.9.6 makes it really hard to get your raised HTTPException,
|
||||
# so this helper implements it manually using a familiar syntax.
|
||||
# FIXME: when we upgrade Pylons, we can replace this with raise
|
||||
# and access environ['pylons.controller.exception']
|
||||
if isinstance(code_or_exception, httpexceptions.HTTPException):
|
||||
exc = code_or_exception
|
||||
else:
|
||||
if type(code_or_exception) is type and issubclass(code_or_exception, httpexceptions.HTTPException):
|
||||
exc_cls = code_or_exception
|
||||
else:
|
||||
exc_cls = httpexceptions.get_exception(code_or_exception)
|
||||
exc = exc_cls(detail, headers, comment)
|
||||
request.environ['r2.controller.exception'] = exc
|
||||
raise exc
|
||||
|
||||
class BaseController(WSGIController):
|
||||
def try_pagecache(self):
|
||||
|
||||
@@ -1380,26 +1380,32 @@ class ClientInfoBar(InfoBar):
|
||||
|
||||
class RedditError(BoringPage):
|
||||
site_tracking = False
|
||||
def __init__(self, title, message, image=None, sr_description=None):
|
||||
def __init__(self, title, message, image=None, sr_description=None,
|
||||
explanation=None):
|
||||
BoringPage.__init__(self, title, loginbox=False,
|
||||
show_sidebar = False,
|
||||
show_sidebar = False,
|
||||
content=ErrorPage(title=title,
|
||||
message=message,
|
||||
image=image,
|
||||
sr_description=sr_description))
|
||||
sr_description=sr_description,
|
||||
explanation=explanation))
|
||||
|
||||
class ErrorPage(Templated):
|
||||
"""Wrapper for an error message"""
|
||||
def __init__(self, title, message, image=None, **kwargs):
|
||||
def __init__(self, title, message, image=None, explanation=None, **kwargs):
|
||||
if not image:
|
||||
letter = random.choice(['a', 'b', 'c', 'd', 'e'])
|
||||
image = 'reddit404' + letter + '.png'
|
||||
# Normalize explanation strings.
|
||||
if explanation:
|
||||
explanation = explanation.lower().rstrip('.') + '.'
|
||||
Templated.__init__(self,
|
||||
title=title,
|
||||
message=message,
|
||||
image_url=image,
|
||||
explanation=explanation,
|
||||
**kwargs)
|
||||
|
||||
|
||||
|
||||
class Over18(Templated):
|
||||
"""The creepy 'over 18' check page for nsfw content."""
|
||||
|
||||
@@ -31,6 +31,9 @@ from r2.lib.filters import unsafe, safemarkdown
|
||||
<h1>${thing.title}</h1>
|
||||
<div class="errorpage-message">
|
||||
${unsafe(safemarkdown(thing.message, wrap=False))}
|
||||
%if thing.explanation:
|
||||
— ${thing.explanation}
|
||||
%endif
|
||||
</div>
|
||||
|
||||
% if thing.sr_description:
|
||||
|
||||
Reference in New Issue
Block a user