diff --git a/TODO.org b/TODO.org index 679a161f..1a5e50a2 100644 --- a/TODO.org +++ b/TODO.org @@ -12,8 +12,8 @@ Draft or long-running issues, WIP, triage, and additional references or context ** TODO STYLE [0/21] -- [ ] Upload :: The ~FileUpload~ component has it's own error handling and display, but the error message display is currently - not customized and results in moving/resizing of DOM elements, see /e.g./ ~UploadForm~ (select unsupported file type). +- [ ] Upload :: The PV ~FileUpload~ component has it's own error handling, but the display is currently + not "customized" and results in moving/resizing of DOM elements, see /e.g./ ~UploadForm~ (select unsupported file type). - [ ] CascadeSelect :: "No available options" is not defined, /cf./ TreeSelect or Dropdown. Styling is different. - [ ] DEADLINE: <2024-08-30 Fri> To harmonize CSS vars/style across views, components, and presets (colours, behaviour, /etc./), to do when addressing [[https://github.com/dieterich-lab/scimodom/issues/14][responsive design]] and accessibility in Q3. Harmonize dark mode and styles for hover, focus, /etc./ across presets. @@ -79,7 +79,7 @@ Draft or long-running issues, WIP, triage, and additional references or context - [ ] Harmonize docstrings /e.g./ ~str~ /vs./ ~String~ /etc./. Order of arguments. Add ~Raises~. Add docstrings where missing. - [X] [2024-02-03 Sat] [[file:~/prj/RMapDFGTRR319/repositories/scimodom/server/src/scimodom/api/__init__.py::E402 module level import not at top of file]] -** TODO GENERAL [7/40] +** TODO GENERAL [8/40] - [ ] download :: Download view temporarily removed (do we want selective/schema DB dumps?), this feature is relegated. Do we want to allow ~Export~ to export "all" selected records, not only those lazy loaded and shown on the screen (~SearchView.vue~)? See @@ -101,7 +101,8 @@ Draft or long-running issues, WIP, triage, and additional references or context - [ ] import :: [2024-02-16 Fri] Add exception if /e.g./ more than 30% of features are unmapped. [[file:~/prj/RMapDFGTRR319/repositories/scimodom/server/src/scimodom/services/assembly.py::Unmapped features are discarded.]] - [ ] import :: What happens if /e.g./ too many rows are skipped or in the worst case there is no records (/e.g./ if chroms are - not formatted short/Ensembl-style)? Maybe we should have a "no commit" fallback and warning/error. + not formatted short/Ensembl-style)? Maybe we should have a "no commit" fallback and warning/error. See /e.g./ during testing upload + with mock data: ~WARNING scimodom.services.annotation.annotate_data.193 | No records found for Kr6uj7QzWfLJ...~. - [ ] import :: ~_validate_columns~ (EUFHeaderImporter) adjusted to check first /non-comment/ row, and raises a ~SpecsError~ if the column count does not match (or if emtpy). On the other hand, EUFDataImporter ignore bad rows. Maybe it would make more sense to NOT validate the column count in EUFHEaderImporter, leave it to EUFDataImporter to handle it, and add a test to check how @@ -131,7 +132,7 @@ Draft or long-running issues, WIP, triage, and additional references or context - [ ] search :: Export: (1) add additional columns /e.g./ taxa_id, cto, RNA type, /etc./ that are hidden from the table, but that requires adding these to the select query, we need to see if that impacts performance; if not, then (2) add a header with at least modification, taxa_id, and cto; if not then (3) format filename (this is the current solution). -- [ ] browse :: Additional information for the ~Dialog~ or for the export? /e.g./ ~sequencing_platform~, ~basecalling~, ~bioinformatics_workflow~, +- [X] browse :: Additional information for the ~Dialog~ or for the export? /e.g./ ~sequencing_platform~, ~basecalling~, ~bioinformatics_workflow~, ~experiment~, and/or ~ProjectContact~ (~Project~ or eventually ~Dataset~ contact). - [ ] router :: All routes to ~/~ with backward/forward navigation? This does not allow either to open a link in a new tab. Also how would diff --git a/server/src/scimodom/api/management.py b/server/src/scimodom/api/management.py index 27226a62..3bdea599 100644 --- a/server/src/scimodom/api/management.py +++ b/server/src/scimodom/api/management.py @@ -6,7 +6,12 @@ from flask_jwt_extended import jwt_required from scimodom.database.database import get_session -from scimodom.services.dataset import DataService, InstantiationError, DatasetError +from scimodom.services.dataset import ( + DataService, + InstantiationError, + DatasetError, + DatasetHeaderError, +) from scimodom.services.project import ProjectService from scimodom.services.mail import get_mail_service import scimodom.utils.utils as utils @@ -112,7 +117,17 @@ def add_dataset(): return ( jsonify( { - "message": f'Failed to upload dataset. Either this dataset already exists, or your bedRMod file header does not match the values you entered. Modify the form or the file header and try again. The message received from the server was: "{exc}". If you are unsure about what happened, click "Cancel" and contact the administrator.' + "message": f'Failed to upload dataset. The message received from the server was: "{exc}". If you are unsure about what happened, click "Cancel" and contact the administrator.' + } + ), + 500, + ) + except DatasetHeaderError as exc: + # no need to log these errors, users should normally handle them + return ( + jsonify( + { + "message": f'Failed to upload dataset. Your bedRMod file header does not match the values you entered. Modify the form or the file header and try again. The message received from the server was: "{exc}". If you are unsure about what happened, click "Cancel" and contact the administrator.' } ), 500, @@ -125,9 +140,7 @@ def add_dataset(): 500, ) + # TODO # WARNING scimodom.services.annotation.annotate_data.193 | No records found for Kr6uj7QzWfLJ... - # DEBUG scimodom.services.dataset.create_dataset.334 | Lifting over dataset from GRCm38 to GRCm39... - # DEBUG scimodom.services.dataset.create_dataset.360 | Added dataset MALPJw5m5CWW to project gRHWaFYU with title = test upload 2, and the following associations: m6A:67. Annotating data now... - # DEBUG scimodom.services.annotation.annotate_data.197 | Annotating records for EUFID MALPJw5m5CWW... return jsonify({"result": "Ok"}), 200 diff --git a/server/src/scimodom/services/dataset.py b/server/src/scimodom/services/dataset.py index 5816b62f..3e7bf94e 100644 --- a/server/src/scimodom/services/dataset.py +++ b/server/src/scimodom/services/dataset.py @@ -35,8 +35,14 @@ class InstantiationError(Exception): class DatasetError(Exception): """Exception for handling Dataset instantiation, - e.g. suspected duplicate entries, mismatch between - header and input values, etc.""" + e.g. suspected duplicate entries.""" + + pass + + +class DatasetHeaderError(Exception): + """Exception for handling mismatch between + dataset header and input values.""" pass @@ -246,7 +252,7 @@ def validate_imported(name: str, form_value: Any, header_value: Any) -> None: f"Expected {form_value} for {name}; got {header_value} (file header). " f"Aborting transaction!" ) - raise DatasetError(msg) + raise DatasetHeaderError(msg) def create_dataset(self) -> None: """Dataset constructor.""" diff --git a/server/tests/unit/services/test_dataset.py b/server/tests/unit/services/test_dataset.py index 0fcbc715..3f3673df 100644 --- a/server/tests/unit/services/test_dataset.py +++ b/server/tests/unit/services/test_dataset.py @@ -17,7 +17,12 @@ ProjectContact, ) import scimodom.database.queries as queries -from scimodom.services.dataset import DataService, InstantiationError, DatasetError +from scimodom.services.dataset import ( + DataService, + InstantiationError, + DatasetError, + DatasetHeaderError, +) from scimodom.services.project import ProjectService import scimodom.utils.utils as utils @@ -143,13 +148,13 @@ def _mock_project_service(session, project): def test_validate_imported_fail(): - with pytest.raises(DatasetError) as exc: + with pytest.raises(DatasetHeaderError) as exc: DataService.validate_imported("test", "a", "b") assert ( str(exc.value) == "Expected a for test; got b (file header). Aborting transaction!" ) - assert exc.type == DatasetError + assert exc.type == DatasetHeaderError def test_validate_imported():