From ab5a4a6b6caae8f7738ad50a8c7fdfb9bea33a0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 6 Sep 2016 14:22:43 +0200 Subject: [PATCH] Custom error pages. These make a distinction between API requests on /api/ (which will return a JSON response) and other requests (which will return HTML). Fixes T49212 --- pillar/__init__.py | 34 +++++++++++++++++++++++++++++++++- pillar/api/nodes/__init__.py | 2 ++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/pillar/__init__.py b/pillar/__init__.py index 77c46173..c37a63ba 100644 --- a/pillar/__init__.py +++ b/pillar/__init__.py @@ -10,10 +10,11 @@ import jinja2 import os import os.path from eve import Eve +from flask import render_template, request +from flask.templating import TemplateNotFound from pillar.api import custom_field_validation from pillar.api.utils import authentication -from pillar.api.utils import gravatar from pillar.web.utils import pretty_date from pillar.web.nodes.routes import url_for_node @@ -277,6 +278,37 @@ class PillarServer(Eve): self.finish_startup() + def register_error_handlers(self): + super(PillarServer, self).register_error_handlers() + + for code in (403, 404, 500): + self.register_error_handler(code, self.pillar_error_handler) + + def pillar_error_handler(self, error_ob): + + if request.full_path.startswith('/%s/' % self.config['URL_PREFIX']): + from pillar.api.utils import jsonify + # This is an API request, so respond in JSON. + return jsonify({ + '_status': 'ERR', + '_code': error_ob.code, + '_message': error_ob.description, + }, status=error_ob.code) + + # See whether we should return an embedded page or a regular one. + if request.is_xhr: + fname = 'errors/%i_embed.html' % error_ob.code + else: + fname = 'errors/%i.html' % error_ob.code + + # Also handle the case where we didn't create a template for this error. + try: + return render_template(fname), error_ob.code + except TemplateNotFound: + self.log.warning('Error template %s for code %i not found', + fname, error_ob.code) + return render_template('errors/500.html'), error_ob.code + def finish_startup(self): self.log.info('Using MongoDB database %r', self.config['MONGO_DBNAME']) diff --git a/pillar/api/nodes/__init__.py b/pillar/api/nodes/__init__.py index 07ba746e..6acdaece 100644 --- a/pillar/api/nodes/__init__.py +++ b/pillar/api/nodes/__init__.py @@ -34,6 +34,8 @@ def share_node(node_id): 'node_type': 1, 'short_code': 1 }) + if not node: + raise wz_exceptions.NotFound('Node %s does not exist.' % node_id) check_permissions('nodes', node, request.method)