From 69de1e372c4ba662799542ca1d9416bae4739ca2 Mon Sep 17 00:00:00 2001 From: Phil Elson Date: Fri, 26 Mar 2021 21:32:36 +0100 Subject: [PATCH 1/2] Make the expert-app trigger the same 404 as the webservice. --- app-config/nginx/nginx.conf | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app-config/nginx/nginx.conf b/app-config/nginx/nginx.conf index 0895e583..8104caa3 100644 --- a/app-config/nginx/nginx.conf +++ b/app-config/nginx/nginx.conf @@ -66,10 +66,20 @@ http { return 302 /auth/login; } + location @proxy_404_error_handler { + # Pass the request on to the webservice. Most likely the URI won't + # exist so we get a 404 from that service instead (good as the 404 + # pages are consistent). + proxy_pass http://cara-webservice:8080/$request_uri; + } + location /voila-server/ { + proxy_intercept_errors on; + # Anything under voila-server or expert-app is authenticated. auth_request /auth/probe; error_page 401 = @error401; + error_page 404 = @proxy_404_error_handler; # cara-app is the name of the voila server in each of docker-compose, # test-cara.web.cern.ch and cara.web.cern.ch. From eb08e1f7aef357800c754a2f79c4abc9998cca62 Mon Sep 17 00:00:00 2001 From: Phil Elson Date: Fri, 26 Mar 2021 22:01:50 +0100 Subject: [PATCH 2/2] Introduce a general error handler (including traceback still) and a 404 handler. --- app.sh | 2 +- cara/apps/calculator/__init__.py | 37 ++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/app.sh b/app.sh index d4fdf7c5..a9fc0e45 100755 --- a/app.sh +++ b/app.sh @@ -1,6 +1,6 @@ if [[ "$APP_NAME" == "cara-webservice" ]]; then echo "Starting the cara webservice" - python -m cara.apps.calculator + python -m cara.apps.calculator --no-debug elif [[ "$APP_NAME" == "cara-voila" ]]; then echo "Starting the voila service" voila app/ --port=8080 --no-browser --base_url=/voila-server/ --Voila.tornado_settings="{'allow_origin': '*'}" diff --git a/cara/apps/calculator/__init__.py b/cara/apps/calculator/__init__.py index 9d7887f9..ab1b45c8 100644 --- a/cara/apps/calculator/__init__.py +++ b/cara/apps/calculator/__init__.py @@ -1,7 +1,10 @@ +import datetime import html import json import os from pathlib import Path +import traceback +import uuid import jinja2 import mistune @@ -29,6 +32,39 @@ class BaseRequestHandler(RequestHandler): else: self.current_user = AnonymousUser() + def write_error(self, status_code: int, **kwargs) -> None: + template = self.settings["template_environment"].get_template( + "page.html.j2") + + error_id = uuid.uuid4() + contents = ( + f'Unfortunately an error occurred when processing your request. ' + f'Please let us know about this issue with as much detail as possible at ' + f'CARA-dev@cern.ch, reporting status ' + f'code {status_code}, the error id of "{error_id}" and the time of the ' + f'request ({datetime.datetime.utcnow()}).



' + ) + # Print the error to the log (and not to the browser!) + if "exc_info" in kwargs: + print(f"ERROR UUID {error_id}") + print(traceback.format_exc()) + self.finish(template.render( + user=self.current_user, + contents=contents + )) + + +class Missing404Handler(BaseRequestHandler): + async def prepare(self): + await super().prepare() + self.set_status(404) + template = self.settings["template_environment"].get_template( + "page.html.j2") + self.finish(template.render( + user=self.current_user, + contents='Unfortunately the page you were looking for does not exist.



' + )) + class ConcentrationModel(BaseRequestHandler): def post(self): @@ -118,6 +154,7 @@ def make_app(debug=False, prefix='/calculator'): urls, debug=debug, template_environment=template_environment, + default_handler_class=Missing404Handler, xsrf_cookies=True, # COOKIE_SECRET being undefined will result in no login information being # presented to the user.