liberapay.com/error.spt
Changaco af8c5eb66d improve handling of request cookies
Pando's `request.headers.cookie` silently ignores parsing errors. This commit removes that attribute entirely by monkey-patching Pando.
2024-07-13 14:20:31 +02:00

133 lines
4.9 KiB
Cheetah

import os.path
import sys
from pando.http import status_strings
from pando.utils import utcnow
from liberapay.exceptions import LazyResponse
from liberapay.i18n.base import HTTP_ERRORS
python_dir = f"python{sys.version_info.major}.{sys.version_info.minor}"
project_root = website.project_root.rstrip(os.path.sep) + os.path.sep
def get_short_traceback(exception):
tb = getattr(exception, '__traceback__', None)
if tb:
r = []
for i in range(25):
frame = tb.tb_frame
filepath = frame.f_code.co_filename.split(os.path.sep)
try:
i = filepath.index(python_dir)
except Exception:
filepath = os.path.sep.join(filepath)
if filepath.startswith(project_root):
filepath = filepath.removeprefix(project_root)
else:
if filepath[i+1] == 'site-packages':
i += 1
filepath = os.path.sep.join(filepath[i+1:])
r.append(f'{filepath}:{tb.tb_lineno} ({frame.f_code.co_name})')
tb = tb.tb_next
if tb is None:
break
return '\n ' + '\n '.join(r)
else:
return ' none'
def render_cookies(request):
return '; '.join(
f"{name}=[{len(value)} bytes]" for name, value in request.cookies.items()
) or 'none'
[----------------------------------------]
sentry_ident = state.get('sentry_ident')
code = response.code
msg = _(HTTP_ERRORS[code]) if code in HTTP_ERRORS else status_strings.get(code, '')
if not msg:
website.tell_sentry(Warning(f"missing error message for HTTP code {code}"))
if isinstance(response, LazyResponse):
response.render_body(state)
err = response.text
if code == 500 and not err:
err = _("Looks like you've found a bug! Sorry for the inconvenience, we'll get it fixed ASAP!")
referer = request.headers.get(b'Referer')
user_agent = request.headers.get(b'User-Agent')
[----------------------------------------] text/html
% extends "templates/layouts/base.html"
% set title = '' if response.html_template is defined else msg
% block content
% if response.html_template is defined
% include response.html_template
% else
% if code >= 400 and code <= 499
% if code == 404
<p>{{ _(
"The requested page could not be found. Please "
"{link_open}contact us{link_close} if you need assistance.",
link_open='<a href="https://liberapay.com/about/contact">'|safe,
link_close='</a>'|safe,
) }}</p>
% else
<p>{{ _(
"Your request has been rejected by our software. Please "
"{link_open}contact us{link_close} if you need assistance.",
link_open='<a href="https://liberapay.com/about/contact">'|safe,
link_close='</a>'|safe,
) }}</p>
% endif
% endif
% if err
% if '\n' in err
<pre>{{ err }}</pre>
% else
<p>{{ _("Error message:") }}</p>
<div class="alert alert-danger">{{ err }}</div>
% endif
% endif
% if sentry_ident
<p>{{ _(
"The details of this error have been recorded. If you decide to contact us, "
"please include the following error identification code in your message: {0}.",
'<code>%s</code>'|safe % sentry_ident
) }}</p>
% else
<br>
<p>{{ _("If you decide to contact us please include the following debugging information in your message:") }}</p>
<pre>URL: {{ website.canonical_scheme }}://{{ request.hostname }}{{ request.line.uri.decoded }}{{ '\n'
}}Method: {{ request.method }}{{ '\n'
}}Referer: {{ repr(referer) }}{{ '\n'
}}User-Agent: {{ repr(user_agent) }}{{ '\n'
}}Cookies: {{ render_cookies(request) }}{{ '\n'
}}IP address: {{ request.source }} ({{ request.source_country }}){{ '\n'
}}Time: {{ utcnow() }}{{ '\n'
}}Response code: {{ code }}{{ '\n'
}}Response message: {{ repr(err) }}{{ '\n'
}}User: {{ user }}{{ '\n'
}}Locale: {{ locale }}{{ '\n'
}}Website version: {{ website.version }}{{ '\n'
}}Traceback:{{
get_short_traceback(response.__cause__ or response)
}}</pre>
% endif
% endif
% endblock
[----------------------------------------] application/json via json_dump
{
"error_code": code,
"error_id": sentry_ident,
"error_message_long": err,
"error_message_short": msg,
"html_template": getattr(response, 'html_template', None),
}
[----------------------------------------] text/plain
{{err or msg}}