mirror of
https://github.com/SonarSource/sonarqube.git
synced 2024-08-12 02:10:16 +02:00
SONAR-4004 handle failed requests
This commit is contained in:
parent
87e9d4629c
commit
458d8b3314
@ -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)));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
<Search component={this.props.component}/>
|
||||
</header>
|
||||
|
||||
{errorMessage && (
|
||||
<div className="alert alert-danger">
|
||||
{errorMessage}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{shouldShowBreadcrumbs && (
|
||||
<Breadcrumbs
|
||||
breadcrumbs={breadcrumbs}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import _ from 'underscore';
|
||||
|
||||
import { INIT, BROWSE, SEARCH, UPDATE_QUERY, START_FETCHING, STOP_FETCHING } from '../actions';
|
||||
import { INIT, BROWSE, SEARCH, UPDATE_QUERY, START_FETCHING, STOP_FETCHING, RAISE_ERROR } from '../actions';
|
||||
|
||||
|
||||
function hasSourceCode (component) {
|
||||
@ -37,7 +37,8 @@ export const initialState = {
|
||||
searchResults: null,
|
||||
searchQuery: '',
|
||||
coverageMetric: null,
|
||||
baseBreadcrumbs: []
|
||||
baseBreadcrumbs: [],
|
||||
errorMessage: null
|
||||
};
|
||||
|
||||
|
||||
@ -55,15 +56,34 @@ export function current (state = initialState, action) {
|
||||
const breadcrumbs = action.breadcrumbs.slice(baseBreadcrumbsLength);
|
||||
const sourceViewer = hasSourceCode(action.component) ? action.component : null;
|
||||
|
||||
return { ...state, baseComponent, components, breadcrumbs, sourceViewer, searchResults: null, searchQuery: '' };
|
||||
return {
|
||||
...state,
|
||||
baseComponent,
|
||||
components,
|
||||
breadcrumbs,
|
||||
sourceViewer,
|
||||
searchResults: null,
|
||||
searchQuery: '',
|
||||
errorMessage: null
|
||||
};
|
||||
case SEARCH:
|
||||
return { ...state, searchResults: action.components };
|
||||
return {
|
||||
...state,
|
||||
searchResults: action.components,
|
||||
errorMessage: null
|
||||
};
|
||||
case UPDATE_QUERY:
|
||||
return { ...state, searchQuery: action.query };
|
||||
case START_FETCHING:
|
||||
return { ...state, fetching: true };
|
||||
case STOP_FETCHING:
|
||||
return { ...state, fetching: false };
|
||||
case RAISE_ERROR:
|
||||
return {
|
||||
...state,
|
||||
errorMessage: action.message,
|
||||
fetching: false
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
@ -7,7 +7,8 @@ import {
|
||||
searchAction,
|
||||
updateQueryAction,
|
||||
startFetching,
|
||||
stopFetching
|
||||
stopFetching,
|
||||
raiseError
|
||||
} from '../../../src/main/js/apps/code/actions';
|
||||
|
||||
|
||||
@ -207,6 +208,20 @@ describe('Code :: Store', () => {
|
||||
.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', () => {
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* globals global: false */
|
||||
require("babel-polyfill");
|
||||
|
||||
var jsdom = require('jsdom');
|
||||
|
||||
|
@ -236,6 +236,7 @@ new_window=New window
|
||||
no_data=No data
|
||||
no_lines_match_your_filter_criteria=No lines match your filter criteria.
|
||||
no_results=No results
|
||||
not_authorized=You are not authorized.
|
||||
not_authorized_to_access_project=You are not authorized to access to this '{0}' project
|
||||
over_x_days=over {0} days
|
||||
over_x_days.short={0} days
|
||||
|
Loading…
Reference in New Issue
Block a user