Skip to content
Snippets Groups Projects
Commit d9cafc68 authored by jaden's avatar jaden
Browse files

add errorService to handle user-facing errors

parent 17a4dc09
No related branches found
No related tags found
1 merge request!223Reports overhaul
/*
* Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/
* Contact: beat.support@idiap.ch
*
* This file is part of the beat.web module of the BEAT platform.
*
* Commercial License Usage
* Licensees holding valid commercial BEAT licenses may use this file in
* accordance with the terms contained in a written agreement between you
* and Idiap. For further information contact tto@idiap.ch
*
* Alternatively, this file may be used under the terms of the GNU Affero
* Public License version 3 as published by the Free Software and appearing
* in the file LICENSE.AGPL included in the packaging of this file.
* The BEAT platform is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero Public License along
* with the BEAT platform. If not, see http://www.gnu.org/licenses/.
*/
/*
* reportError
* Desc:
* Watches the ErrorService's error list and processes an error if
* its not empty.
* 'Processing': showing a modal to the user about the error.
*
*/
angular.module('reportApp')
.directive("reportError", ['ErrorService', '$timeout', function(ErrorService, $timeout){
return {
scope: {
},
restrict: 'E',
link: function(scope){
scope.error = null;
const processError = () => {
// if theres no error, return
if(!ErrorService._hasError){
return;
}
// save our error
scope.error = ErrorService._getError();
// pop up the modal
$('#errorReportModal').modal();
};
$timeout(() => {
$('#errorReportModal').on('hidden.bs.modal', () => {
// finished processing the last error
scope.error = null;
// process the next one, if there is one
processError();
});
}, 0);
scope.$watch(ErrorService._hasError, processError);
},
template: `
<bootstrap-modal dom-id='errorReportModal' button-cancel-text='Continue'>
<b-title>
Error
</b-title>
<b-content>
<p>There was an error:</p>
<p>{{ error.message }}</p>
<pre>{{ error.error.message }}</pre>
</b-content>
</bootstrap-modal>
`
};
}]);
...@@ -26,14 +26,19 @@ ...@@ -26,14 +26,19 @@
* Displays a modal for locking the current report. * Displays a modal for locking the current report.
*/ */
angular.module('reportApp') angular.module('reportApp')
.directive("reportLock", ['ReportService', function(ReportService){ .directive("reportLock", ['ReportService', 'ErrorService', function(ReportService, ErrorService){
return { return {
scope: { scope: {
}, },
restrict: 'E', restrict: 'E',
link: function(scope, el){ link: function(scope, el){
// sends the request to lock the report // sends the request to lock the report
scope.lockReport = ReportService.lockReport; scope.lockReport = () => {
return ReportService.lockReport()
.catch(e, () => {
ErrorService.logError(e, `Could not lock the report.`);
});
}
}, },
template: ` template: `
<bootstrap-modal dom-id='lockReportModal' button-submit-text='Lock' button-submit-func='lockReport'> <bootstrap-modal dom-id='lockReportModal' button-submit-text='Lock' button-submit-func='lockReport'>
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
* Visible or Public. * Visible or Public.
*/ */
angular.module('reportApp') angular.module('reportApp')
.directive("reportPublish", ['reportFactory', 'ReportService', '$timeout', function(reportFactory, ReportService, $timeout){ .directive("reportPublish", ['reportFactory', 'ReportService', '$timeout', 'ErrorService', function(reportFactory, ReportService, $timeout, ErrorService){
return { return {
scope: { scope: {
}, },
...@@ -49,8 +49,8 @@ angular.module('reportApp') ...@@ -49,8 +49,8 @@ angular.module('reportApp')
res.data.forEach(a => scope.algorithms.push(a)); res.data.forEach(a => scope.algorithms.push(a));
scope.algorithms.forEach(a => { scope.radios[a] = ''; }); scope.algorithms.forEach(a => { scope.radios[a] = ''; });
}) })
.catch(error => { .catch(e => {
console.error(error); ErrorService.logError(e, `Could not publish the report.`);
}) })
; ;
}; };
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
* saves the current report * saves the current report
*/ */
angular.module('reportApp') angular.module('reportApp')
.directive("reportSave", ['GroupsService', 'ReportService', 'reportFactory', function(GroupsService, ReportService, reportFactory){ .directive("reportSave", ['GroupsService', 'ReportService', 'reportFactory', 'ErrorService', function(GroupsService, ReportService, reportFactory, ErrorService){
return { return {
scope: { scope: {
}, },
...@@ -42,6 +42,9 @@ angular.module('reportApp') ...@@ -42,6 +42,9 @@ angular.module('reportApp')
}; };
return reportFactory.updateReport(ReportService.author, ReportService.name, saveData, '') return reportFactory.updateReport(ReportService.author, ReportService.name, saveData, '')
.catch(e => {
ErrorService.logError(e, `Could not save the report.`);
});
}; };
el.bind('click', saveReport); el.bind('click', saveReport);
......
/*
* Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/
* Contact: beat.support@idiap.ch
*
* This file is part of the beat.web module of the BEAT platform.
*
* Commercial License Usage
* Licensees holding valid commercial BEAT licenses may use this file in
* accordance with the terms contained in a written agreement between you
* and Idiap. For further information contact tto@idiap.ch
*
* Alternatively, this file may be used under the terms of the GNU Affero
* Public License version 3 as published by the Free Software and appearing
* in the file LICENSE.AGPL included in the packaging of this file.
* The BEAT platform is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero Public License along
* with the BEAT platform. If not, see http://www.gnu.org/licenses/.
*/
/*
* ErrorService
* Desc:
* Centralizes user-facing error-handling in the reports app.
* Other parts of the app can register errors (i.e. 404s, server errors,
* invalid input, etc.) with the ErrorService.
* The ErrorService will (one at a time & synchronously!) pop up an error
* modal (directives/error.js, "report-error") to let the user know.
*/
angular.module('reportApp').factory('ErrorService', [function(){
const es = {
_errors: [],
_hasError: false
};
class ReportError {
constructor (errorObj, message) {
this._error = errorObj;
this._message = message || '';
}
get error () {
return this._error;
}
get message () {
return this._message;
}
}
es.logError = (error, message) => {
const newErr = new ReportError(error, message);
es._errors.push(newErr);
_hasError = true;
};
es._getError = () => {
const err = es._errors.shift();
if(es._errors.length === 0){
es._hasError = false;
}
return err;
}
return es;
}]);
...@@ -90,6 +90,7 @@ ...@@ -90,6 +90,7 @@
<script src="{% fingerprint "reports/app/services/urlService.js" %}" type="text/javascript" charset="utf-8"></script> <script src="{% fingerprint "reports/app/services/urlService.js" %}" type="text/javascript" charset="utf-8"></script>
<script src="{% fingerprint "reports/app/services/reportService.js" %}" type="text/javascript" charset="utf-8"></script> <script src="{% fingerprint "reports/app/services/reportService.js" %}" type="text/javascript" charset="utf-8"></script>
<script src="{% fingerprint "reports/app/services/plotService.js" %}" type="text/javascript" charset="utf-8"></script> <script src="{% fingerprint "reports/app/services/plotService.js" %}" type="text/javascript" charset="utf-8"></script>
<script src="{% fingerprint "reports/app/services/errorService.js" %}" type="text/javascript" charset="utf-8"></script>
<!-- directives --> <!-- directives -->
...@@ -100,6 +101,7 @@ ...@@ -100,6 +101,7 @@
<script src="{% fingerprint "reports/app/directives/publish.js" %}" type="text/javascript" charset="utf-8"></script> <script src="{% fingerprint "reports/app/directives/publish.js" %}" type="text/javascript" charset="utf-8"></script>
<script src="{% fingerprint "reports/app/directives/lock.js" %}" type="text/javascript" charset="utf-8"></script> <script src="{% fingerprint "reports/app/directives/lock.js" %}" type="text/javascript" charset="utf-8"></script>
<script src="{% fingerprint "reports/app/directives/save.js" %}" type="text/javascript" charset="utf-8"></script> <script src="{% fingerprint "reports/app/directives/save.js" %}" type="text/javascript" charset="utf-8"></script>
<script src="{% fingerprint "reports/app/directives/error.js" %}" type="text/javascript" charset="utf-8"></script>
<!-- edit view --> <!-- edit view -->
{% if not report_number and report.get_status_display == 'Editable' and owner %} {% if not report_number and report.get_status_display == 'Editable' and owner %}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment