From 458d8b33149bed4e3b1c0e579555734ee1d27b02 Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Tue, 29 Dec 2015 14:03:22 +0100 Subject: SONAR-4004 handle failed requests --- .../src/main/js/apps/code/actions/index.js | 30 +++++++++++++++++++++- .../src/main/js/apps/code/components/Code.js | 16 +++++++++++- .../src/main/js/apps/code/reducers/index.js | 28 +++++++++++++++++--- server/sonar-web/tests/apps/code/store-test.js | 17 +++++++++++- server/sonar-web/tests/jsdom-setup.js | 1 + 5 files changed, 85 insertions(+), 7 deletions(-) (limited to 'server') diff --git a/server/sonar-web/src/main/js/apps/code/actions/index.js b/server/sonar-web/src/main/js/apps/code/actions/index.js index a68df6429b7..53437e244c8 100644 --- a/server/sonar-web/src/main/js/apps/code/actions/index.js +++ b/server/sonar-web/src/main/js/apps/code/actions/index.js @@ -26,6 +26,7 @@ export const SEARCH = 'SEARCH'; export const UPDATE_QUERY = 'UPDATE_QUERY'; export const START_FETCHING = 'START_FETCHING'; export const STOP_FETCHING = 'STOP_FETCHING'; +export const RAISE_ERROR = 'RAISE_ERROR'; export function initComponentAction (component, breadcrumbs = []) { @@ -67,6 +68,13 @@ export function stopFetching () { return { type: STOP_FETCHING }; } +export function raiseError (message) { + return { + type: RAISE_ERROR, + message + }; +} + function getPath (componentKey) { return '/' + encodeURIComponent(componentKey); @@ -107,6 +115,22 @@ let requestTree = (query, baseComponent, dispatch) => { }; requestTree = _.debounce(requestTree, 250); +async function getErrorMessage (response) { + switch (response.status) { + case 401: + return window.t('not_authorized'); + default: + try { + let json = await response.json(); + return json['err_msg'] || + (json.errors && _.pluck(json.errors, 'msg').join('. ')) || + window.t('default_error_message'); + } catch (e) { + return window.t('default_error_message'); + } + } +} + export function initComponent (componentKey, breadcrumbs) { return dispatch => { dispatch(startFetching()); @@ -125,7 +149,11 @@ export function browse (componentKey) { dispatch(browseAction(component, children, breadcrumbs)); }) .then(() => dispatch(pushPath(getPath(componentKey)))) - .then(() => dispatch(stopFetching())); + .then(() => dispatch(stopFetching())) + .catch(e => { + getErrorMessage(e.response) + .then(message => dispatch(raiseError(message))); + }); }; } diff --git a/server/sonar-web/src/main/js/apps/code/components/Code.js b/server/sonar-web/src/main/js/apps/code/components/Code.js index 2e54f46c955..53365d97d46 100644 --- a/server/sonar-web/src/main/js/apps/code/components/Code.js +++ b/server/sonar-web/src/main/js/apps/code/components/Code.js @@ -33,7 +33,15 @@ class Code extends Component { } render () { - const { fetching, baseComponent, components, breadcrumbs, sourceViewer, coverageMetric, searchResults } = this.props; + const { + fetching, + baseComponent, + components, + breadcrumbs, + sourceViewer, + coverageMetric, + searchResults, + errorMessage } = this.props; const shouldShowBreadcrumbs = Array.isArray(breadcrumbs) && breadcrumbs.length > 1; const shouldShowSearchResults = !!searchResults; const shouldShowSourceViewer = !!sourceViewer; @@ -55,6 +63,12 @@ class Code extends Component { + {errorMessage && ( +
+ {errorMessage} +
+ )} + {shouldShowBreadcrumbs && ( { .to.equal(''); }); }); + describe('errorMessage', () => { + it('should be set', () => { + expect(current(initialState, raiseError('error!')).errorMessage) + .to.equal('error!'); + }); + + it('should be reset', () => { + const stateBefore = Object.assign({}, initialState, { errorMessage: 'error!' }); + expect(current(stateBefore, browseAction(exampleComponent)).errorMessage) + .to.be.null; + expect(current(stateBefore, searchAction(exampleComponents)).errorMessage) + .to.be.null; + }); + }); }); describe('bucket', () => { it('should add initial component', () => { diff --git a/server/sonar-web/tests/jsdom-setup.js b/server/sonar-web/tests/jsdom-setup.js index e911cbeb95b..f1d92d7d818 100644 --- a/server/sonar-web/tests/jsdom-setup.js +++ b/server/sonar-web/tests/jsdom-setup.js @@ -1,4 +1,5 @@ /* globals global: false */ +require("babel-polyfill"); var jsdom = require('jsdom'); -- cgit v1.2.3