diff --git a/openflexure_microscope/api/app.py b/openflexure_microscope/api/app.py index 2a310f0c..d288bf65 100644 --- a/openflexure_microscope/api/app.py +++ b/openflexure_microscope/api/app.py @@ -23,7 +23,7 @@ import os from datetime import datetime import pkg_resources -from flask import abort, send_file +from flask import abort, send_file, jsonify from flask_cors import CORS, cross_origin from labthings import create_app from labthings.extensions import find_extensions @@ -105,6 +105,20 @@ app, labthing = create_app( # Enable CORS for some routes outside of LabThings cors: CORS = CORS(app) +# Enable correct handling of Marshmallow/Webargs validation errors +# Return validation errors as JSON +# (see https://webargs.readthedocs.io/en/latest/framework_support.html) +@app.errorhandler(422) +@app.errorhandler(400) +def handle_error(err): + headers = err.data.get("headers", None) + messages = err.data.get("messages", ["Invalid request."]) + if headers: + return jsonify({"errors": messages}), err.code, headers + else: + return jsonify({"errors": messages}), err.code + + # Use custom JSON encoder labthing.json_encoder = JSONEncoder app.json_encoder = JSONEncoder diff --git a/openflexure_microscope/api/default_extensions/scan.py b/openflexure_microscope/api/default_extensions/scan.py index 5a2365c4..782ad8f4 100644 --- a/openflexure_microscope/api/default_extensions/scan.py +++ b/openflexure_microscope/api/default_extensions/scan.py @@ -2,6 +2,7 @@ import datetime import logging import time import uuid +import marshmallow from functools import reduce from typing import Dict, List, Optional, Tuple @@ -361,7 +362,11 @@ class ScanExtension(BaseExtension): class TileScanArgs(FullCaptureArgs): namemode = fields.String(missing="coordinates", example="coordinates") - grid = fields.List(fields.Integer, missing=[3, 3, 3], example=[3, 3, 3]) + grid = fields.List( + fields.Integer(validate=marshmallow.validate.Range(min=1)), + missing=[3, 3, 3], + example=[3, 3, 3], + ) style = fields.String(missing="raster") autofocus_dz = fields.Integer(missing=50) fast_autofocus = fields.Boolean(missing=False) diff --git a/openflexure_microscope/api/static/src/components/tabContentComponents/captureComponents/paneCapture.vue b/openflexure_microscope/api/static/src/components/tabContentComponents/captureComponents/paneCapture.vue index 1de921e0..1c3a0c85 100644 --- a/openflexure_microscope/api/static/src/components/tabContentComponents/captureComponents/paneCapture.vue +++ b/openflexure_microscope/api/static/src/components/tabContentComponents/captureComponents/paneCapture.vue @@ -155,7 +155,7 @@ v-model="scanStepSize.z" class="uk-input uk-form-small" type="number" - name="inputPositionZx" + name="inputPositionZ" /> @@ -172,6 +172,7 @@ class="uk-input uk-form-small" type="number" name="inputPositionX" + min="1" /> @@ -186,6 +187,7 @@ class="uk-input uk-form-small" type="number" name="inputPositionY" + min="1" /> @@ -199,7 +201,8 @@ v-model="scanSteps.z" class="uk-input uk-form-small" type="number" - name="inputPositionZx" + name="inputPositionZ" + min="1" />