mirror of
https://github.com/valitydev/redash.git
synced 2024-11-07 01:25:16 +00:00
Improve error handling mechanism (related to getredash/redash#2162)
This commit is contained in:
parent
6441c4b52d
commit
1bfea8b493
64
client/app/components/app-view/index.js
Normal file
64
client/app/components/app-view/index.js
Normal file
@ -0,0 +1,64 @@
|
||||
import template from './template.html';
|
||||
|
||||
export default function init(ngModule) {
|
||||
ngModule.component('appView', {
|
||||
template,
|
||||
controller($rootScope, $route, Auth) {
|
||||
this.showHeaderAndFooter = false;
|
||||
|
||||
$rootScope.$on('$routeChangeStart', (event, route) => {
|
||||
if (route.$$route.authenticated) {
|
||||
// For routes that need authentication, check if session is already
|
||||
// loaded, and load it if not.
|
||||
Auth.logger('Requested authenticated route: ', route);
|
||||
if (Auth.isAuthenticated()) {
|
||||
this.showHeaderAndFooter = true;
|
||||
} else {
|
||||
event.preventDefault();
|
||||
Auth.loadSession().then(() => {
|
||||
if (Auth.isAuthenticated()) {
|
||||
this.showHeaderAndFooter = true;
|
||||
Auth.logger('Loaded session');
|
||||
$route.reload();
|
||||
} else {
|
||||
throw new Error('Need to login');
|
||||
}
|
||||
}).catch(() => {
|
||||
Auth.logger('Need to login, redirecting');
|
||||
Auth.login();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.showHeaderAndFooter = false;
|
||||
}
|
||||
});
|
||||
|
||||
this.error = null;
|
||||
|
||||
$rootScope.$on('appViewError', (event, error) => {
|
||||
if ((error !== null) && (error !== undefined) && (error !== '')) {
|
||||
this.error = error instanceof Error ? error : new Error('' + error);
|
||||
} else {
|
||||
this.error = null;
|
||||
}
|
||||
});
|
||||
|
||||
$rootScope.$on('$routeChangeSuccess', () => {
|
||||
$rootScope.$broadcast('appViewError', null);
|
||||
});
|
||||
|
||||
$rootScope.$on('appViewRejection', (event, rejection) => {
|
||||
let error = null;
|
||||
switch (rejection.status) {
|
||||
case 403: error = new Error(''); break;
|
||||
default: error = new Error(rejection.data.message); break;
|
||||
}
|
||||
$rootScope.$broadcast('appViewError', error);
|
||||
});
|
||||
|
||||
$rootScope.$on('$routeChangeError', (event, current, previous, rejection) => {
|
||||
$rootScope.$broadcast('appViewRejection', rejection);
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
6
client/app/components/app-view/template.html
Normal file
6
client/app/components/app-view/template.html
Normal file
@ -0,0 +1,6 @@
|
||||
<app-header ng-if="$ctrl.showHeaderAndFooter"></app-header>
|
||||
<div ng-if="$ctrl.error" class="container-fluid">
|
||||
<div class="alert alert-danger">{{ $ctrl.error.message }}</div>
|
||||
</div>
|
||||
<div ng-hide="$ctrl.error" ng-view></div>
|
||||
<footer ng-if="$ctrl.showHeaderAndFooter"></footer>
|
@ -1,19 +0,0 @@
|
||||
export default function init(ngModule) {
|
||||
ngModule.component('routeStatus', {
|
||||
template: '<overlay ng-if="$ctrl.permissionDenied">You do not have permission to load this page.',
|
||||
|
||||
controller($rootScope) {
|
||||
this.permissionDenied = false;
|
||||
|
||||
$rootScope.$on('$routeChangeSuccess', () => {
|
||||
this.permissionDenied = false;
|
||||
});
|
||||
|
||||
$rootScope.$on('$routeChangeError', (event, current, previous, rejection) => {
|
||||
if (rejection.status === 403) {
|
||||
this.permissionDenied = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
@ -84,11 +84,6 @@ function registerPages() {
|
||||
ngModule.config(($routeProvider) => {
|
||||
each(routes, (route, path) => {
|
||||
logger('Registering route: %s', path);
|
||||
// This is a workaround, to make sure app-header and footer are loaded only
|
||||
// for the authenticated routes.
|
||||
// We should look into switching to ui-router, that has built in support for
|
||||
// such things.
|
||||
route.template = `<app-header></app-header><route-status></route-status>${route.template}<footer></footer>`;
|
||||
route.authenticated = true;
|
||||
$routeProvider.when(path, route);
|
||||
});
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
<body>
|
||||
<section>
|
||||
<div ng-view></div>
|
||||
<app-view></app-view>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
<body>
|
||||
<section>
|
||||
<div ng-view></div>
|
||||
<app-view></app-view>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -164,12 +164,16 @@ function DashboardCtrl(
|
||||
this.dashboard = Dashboard.get({ slug: $routeParams.dashboardSlug }, (dashboard) => {
|
||||
Events.record('view', 'dashboard', dashboard.id);
|
||||
renderDashboard(dashboard, force);
|
||||
}, () => {
|
||||
// error...
|
||||
// try again. we wrap loadDashboard with throttle so it doesn't happen too often.
|
||||
// we might want to consider exponential backoff and also move this as a general
|
||||
// solution in $http/$resource for all AJAX calls.
|
||||
this.loadDashboard();
|
||||
}, (error) => {
|
||||
const statusGroup = Math.floor(error.status / 100);
|
||||
if (statusGroup === 5) {
|
||||
// recoverable errors - all 5** (server is temporarily unavailable
|
||||
// for some reason, but it should get up soon).
|
||||
this.loadDashboard();
|
||||
} else {
|
||||
// all kind of 4** errors are not recoverable, so just display them
|
||||
$rootScope.$broadcast('appViewRejection', error);
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
|
@ -24,6 +24,7 @@ function getLocalSessionData() {
|
||||
|
||||
function AuthService($window, $location, $q, $http) {
|
||||
const Auth = {
|
||||
logger,
|
||||
isAuthenticated() {
|
||||
const sessionData = getLocalSessionData();
|
||||
return sessionData.loaded && sessionData.user.id;
|
||||
@ -112,21 +113,4 @@ export default function init(ngModule) {
|
||||
ngModule.config(($httpProvider) => {
|
||||
$httpProvider.interceptors.push('apiKeyHttpInterceptor');
|
||||
});
|
||||
|
||||
ngModule.run(($location, $window, $rootScope, $route, Auth) => {
|
||||
$rootScope.$on('$routeChangeStart', (event, to) => {
|
||||
if (to.authenticated && !Auth.isAuthenticated()) {
|
||||
logger('Requested authenticated route: ', to);
|
||||
event.preventDefault();
|
||||
// maybe we only miss the session? try to load session
|
||||
Auth.loadSession().then(() => {
|
||||
logger('Loaded session');
|
||||
$route.reload();
|
||||
}).catch(() => {
|
||||
logger('Need to login, redirecting');
|
||||
Auth.login();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user