diff --git a/invenio_theme_tugraz/config.py b/invenio_theme_tugraz/config.py index 1c760bc..a655223 100644 --- a/invenio_theme_tugraz/config.py +++ b/invenio_theme_tugraz/config.py @@ -35,10 +35,16 @@ THEME_TUGRAZ_PRODUCTION = False has to be 'INVENIO_THEME_TUGRAZ_PRODUCTION'. """ +THEME_TUGRAZ_SUPPORT_EMAIL = "" +"""Shown as contact-info on default error-page.""" + # Invenio-theme # ============ # See https://invenio-theme.readthedocs.io/en/latest/configuration.html # +THEME_500_TEMPLATE = "invenio_theme_tugraz/default_error.html" +"""Used for any internal server errors and uncaught exceptions.""" + THEME_LOGO = "images/tug_logo.png" """TU Graz logo""" diff --git a/invenio_theme_tugraz/templates/invenio_theme_tugraz/default_error.html b/invenio_theme_tugraz/templates/invenio_theme_tugraz/default_error.html new file mode 100644 index 0000000..d6f2bfa --- /dev/null +++ b/invenio_theme_tugraz/templates/invenio_theme_tugraz/default_error.html @@ -0,0 +1,21 @@ +{# + Copyright (C) 2024 Graz University of Technology. + + invenio-theme-tugraz is free software; you can redistribute it and/or + modify it under the terms of the MIT License; see LICENSE file for more + details. + #} + + {% extends config.THEME_ERROR_TEMPLATE %} + + {% block message %} +

{{ _('Internal server error') }}

+

+ {{ _( + 'Please contact our support + to let us know about this error.' + ).format(support_email=config.THEME_TUGRAZ_SUPPORT_EMAIL) + }} +

+ {# TODO: provide g.sentry_event_id here once sentry is configured, cf. invenio_theme/500.html #} + {% endblock message %} diff --git a/invenio_theme_tugraz/views.py b/invenio_theme_tugraz/views.py index 614d18e..4717504 100644 --- a/invenio_theme_tugraz/views.py +++ b/invenio_theme_tugraz/views.py @@ -11,7 +11,7 @@ from functools import wraps from typing import Dict -from flask import Blueprint, g, redirect, render_template, url_for +from flask import Blueprint, current_app, g, redirect, render_template, url_for from flask_login import current_user, login_required from invenio_rdm_records.proxies import current_rdm_records from invenio_records_global_search.resources.serializers import ( @@ -86,12 +86,27 @@ def cast_to_dict(attr_dict): return AttrDict.to_dict(attr_dict) +def default_error_handler(e: Exception): + """Called when an otherwise unhandled error occurs.""" + # TODO: use sentry here once it's configured + # information we might want to log for debugging the error: + # - `flask.request`, a proxy to the current http-request in which the error occured + # - `flask.session`, a proxy to the current http-session + # - `e`, the passed-in exception + # to get proxied-to objects: `flask.request._get_current_object()` + + return render_template(current_app.config["THEME_500_TEMPLATE"]), 500 + + def ui_blueprint(app): """Blueprint for the routes and resources provided by Invenio-theme-tugraz.""" routes = app.config.get("TUG_ROUTES") blueprint.add_url_rule(routes["index"], view_func=index) + # base case for any otherwise unhandled exception + app.register_error_handler(Exception, default_error_handler) + return blueprint