diff --git a/openflexure_microscope/api/app.py b/openflexure_microscope/api/app.py index 4a8556d3..3ca9f857 100644 --- a/openflexure_microscope/api/app.py +++ b/openflexure_microscope/api/app.py @@ -17,10 +17,12 @@ from flask import ( from flask.views import MethodView from werkzeug.exceptions import default_exceptions +from serial import SerialException from flask_cors import CORS from openflexure_microscope.api.utilities import list_routes +from openflexure_microscope.api.exceptions import JSONExceptionHandler from openflexure_microscope import Microscope, config from openflexure_microscope.exceptions import LockError @@ -52,31 +54,8 @@ app.url_map.strict_slashes = False CORS(app, resources=r'/api/*') - # Make errors more API friendly - -def _handle_http_exception(e): - return make_response( - jsonify({ - 'status_code': e.code, - 'error': e.name, - 'details': e.description - }), - e.code) - -for code in default_exceptions: - app.errorhandler(code)(_handle_http_exception) - -def _handle_lock_exception(e): - return make_response( - jsonify({ - 'status_code': 423, - 'error': e.code, - 'details': e.message - }), - 423) - -app.errorhandler(LockError)(_handle_lock_exception) +handler = JSONExceptionHandler(app) # After app starts, but before first request, attach hardware to global microscope @app.before_first_request @@ -87,6 +66,7 @@ def attach_microscope(): logging.debug("Creating camera object...") api_camera = StreamingCamera(config=openflexurerc) + logging.debug("Creating stage object...") api_stage = Stage("/dev/ttyUSB0") diff --git a/openflexure_microscope/api/exceptions.py b/openflexure_microscope/api/exceptions.py new file mode 100644 index 00000000..86a141fc --- /dev/null +++ b/openflexure_microscope/api/exceptions.py @@ -0,0 +1,31 @@ +from flask import jsonify +from werkzeug.exceptions import default_exceptions +from werkzeug.exceptions import HTTPException + +from pprint import pprint + +class JSONExceptionHandler(object): + + def __init__(self, app=None): + if app: + self.init_app(app) + + def std_handler(self, error): + message = error.description if isinstance(error, HTTPException) else error.message + status_code = error.code if isinstance(error, HTTPException) else 500 + + response = { + 'status_code': status_code, + 'message': message + } + return jsonify(response) + + + def init_app(self, app): + self.app = app + self.register(HTTPException) + for code, v in default_exceptions.items(): + self.register(code) + + def register(self, exception_or_code, handler=None): + self.app.errorhandler(exception_or_code)(handler or self.std_handler) \ No newline at end of file