mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
feature(core-app): CB-217 add expired session global error refactoring
CB-217
This commit is contained in:
@@ -21,7 +21,7 @@ export * from './shared/NavigationTabs/NavigationTabsService';
|
||||
export * from './shared/NavigationTabs/TabNavigationContext';
|
||||
export * from './shared/ToolsPanel/LogViewTab/LogViewerMenuService';
|
||||
export * from './shared/ToolsPanel/LogViewTab/LogViewerService';
|
||||
export * from './shared/SessionExpire/SessionExpireService';
|
||||
export * from './shared/SessionExpireDialog/SessionExpiredDialogService';
|
||||
export * from './NavigationTree/NavigationTreeService';
|
||||
export * from './NavigationTree/NavigationTreeContextMenuService';
|
||||
export * from './AppLocaleService';
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* cloudbeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
|
||||
import { ActionSnackbar } from '@cloudbeaver/core-blocks';
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import { CommonDialogService } from '@cloudbeaver/core-dialogs';
|
||||
import { ENotificationType, NotificationService } from '@cloudbeaver/core-events';
|
||||
import { SessionExpireService } from '@cloudbeaver/core-root';
|
||||
|
||||
import { SessionExpiredDialog } from './SessionExpiredDialog';
|
||||
|
||||
@injectable()
|
||||
export class SessionExpiredDialogService {
|
||||
constructor(
|
||||
private notificationService: NotificationService,
|
||||
private commonDialogService: CommonDialogService,
|
||||
private sessionExpireService: SessionExpireService
|
||||
) {
|
||||
}
|
||||
|
||||
subscribe(): void {
|
||||
this.sessionExpireService.onSessionExpire.subscribe(this.sessionExpiredInterceptor.bind(this));
|
||||
}
|
||||
|
||||
private async sessionExpiredInterceptor(): Promise<any> {
|
||||
try {
|
||||
await this.commonDialogService.open(SessionExpiredDialog, null);
|
||||
} finally {
|
||||
this.notificationService.customNotification(() => ActionSnackbar, {
|
||||
actionText: 'app_root_session_expired_reload',
|
||||
onAction: () => location.reload(),
|
||||
}, { title: 'app_root_session_expired_title', persistent: true, type: ENotificationType.Error });
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -11,10 +11,11 @@ import {
|
||||
NavigationTabsService,
|
||||
NavigationTreeContextMenuService,
|
||||
LogViewerMenuService,
|
||||
ConnectionSchemaManagerService, SessionExpireService
|
||||
ConnectionSchemaManagerService, SessionExpiredDialogService
|
||||
} from '@cloudbeaver/core-app';
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import { ExceptionsCatcherService } from '@cloudbeaver/core-events';
|
||||
import { SessionExpireService } from '@cloudbeaver/core-root';
|
||||
import { ThemeService } from '@cloudbeaver/core-theming';
|
||||
|
||||
/**
|
||||
@@ -31,6 +32,7 @@ export class AppBootstrap {
|
||||
private connectionDialogService: ConnectionDialogsService,
|
||||
private logViewerMenuService: LogViewerMenuService,
|
||||
private sessionExpireService: SessionExpireService,
|
||||
private sessionExpireDialogService: SessionExpiredDialogService,
|
||||
private navigationTreeContextMenuService: NavigationTreeContextMenuService,
|
||||
private navigationTabsService: NavigationTabsService,
|
||||
private connectionSchemaManagerService: ConnectionSchemaManagerService,
|
||||
@@ -39,7 +41,7 @@ export class AppBootstrap {
|
||||
register(): void | Promise<void> {
|
||||
this.exceptionsCatcherService.subscribe();
|
||||
this.sessionExpireService.subscribe();
|
||||
|
||||
this.sessionExpireDialogService.subscribe();
|
||||
this.connectionSchemaManagerService.registerCallbacks();
|
||||
this.navigationTreeContextMenuService.registerMenuItems();
|
||||
this.connectionDialogService.registerMenuItems();
|
||||
|
||||
@@ -37,7 +37,7 @@ import {
|
||||
CoreSettingsService,
|
||||
AdministrationTopAppBarBootstrapService,
|
||||
AppLocaleService,
|
||||
SessionExpireService
|
||||
SessionExpiredDialogService
|
||||
} from '@cloudbeaver/core-app';
|
||||
import {
|
||||
AuthInfoService,
|
||||
@@ -75,7 +75,7 @@ import {
|
||||
ServerSettingsService,
|
||||
ServerConfigResource,
|
||||
PermissionsResource,
|
||||
SessionResource,
|
||||
SessionResource, SessionExpireService
|
||||
} from '@cloudbeaver/core-root';
|
||||
import { RouterService, ScreenService } from '@cloudbeaver/core-routing';
|
||||
import { EnvironmentService, GraphQLService } from '@cloudbeaver/core-sdk';
|
||||
@@ -120,6 +120,7 @@ export const coreManifest: PluginManifest = {
|
||||
CoreSettingsService,
|
||||
CommonDialogService,
|
||||
SessionExpireService,
|
||||
SessionExpiredDialogService,
|
||||
ConnectionsLocaleService,
|
||||
ConnectionDialogsService,
|
||||
ConnectionSchemaManagerService,
|
||||
|
||||
@@ -14,7 +14,6 @@ import { EventsSettingsService } from './EventsSettingsService';
|
||||
import {
|
||||
ENotificationType, INotification, INotificationExtraProps, INotificationOptions, NotificationComponent
|
||||
} from './INotification';
|
||||
import { SessionError } from './SessionError';
|
||||
|
||||
|
||||
@injectable()
|
||||
@@ -95,11 +94,7 @@ export class NotificationService {
|
||||
|
||||
logException(exception: Error | GQLError, message?: string, silent?: boolean): void {
|
||||
const exceptionMessage = hasDetails(exception) ? exception.errorText : exception.message || exception.name;
|
||||
const isSessionExpired = exception instanceof SessionError;
|
||||
|
||||
if(isSessionExpired && message) {
|
||||
message = exception.message
|
||||
}
|
||||
if (!silent) {
|
||||
this.logError({
|
||||
title: message || exceptionMessage,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
export * from './NotificationService';
|
||||
export * from './INotification';
|
||||
export * from './DbeaverError';
|
||||
export * from './SessionError'
|
||||
export * from './ExceptionsCatcherService';
|
||||
export * from './EventsSettingsService';
|
||||
|
||||
+4
-17
@@ -8,16 +8,13 @@
|
||||
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
import { ActionSnackbar } from '@cloudbeaver/core-blocks';
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import { CommonDialogService } from '@cloudbeaver/core-dialogs';
|
||||
import { ENotificationType, NotificationService } from '@cloudbeaver/core-events';
|
||||
import { SessionError } from '@cloudbeaver/core-events';
|
||||
import {
|
||||
GQLError, GraphQLService, EServerErrorCode
|
||||
} from '@cloudbeaver/core-sdk';
|
||||
|
||||
import { SessionExpiredDialog } from './SessionExpiredDialog';
|
||||
import { SessionError } from './SessionError';
|
||||
|
||||
|
||||
@injectable()
|
||||
export class SessionExpireService {
|
||||
@@ -26,8 +23,6 @@ export class SessionExpireService {
|
||||
onSessionExpire = new Subject();
|
||||
constructor(
|
||||
private graphQLService: GraphQLService,
|
||||
private notificationService: NotificationService,
|
||||
private commonDialogService: CommonDialogService
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -42,18 +37,10 @@ export class SessionExpireService {
|
||||
if (exception instanceof GQLError &&
|
||||
exception.errorCode === EServerErrorCode.sessionExpired &&
|
||||
!this.isNotifiedAboutExpiredSession) {
|
||||
const e = new SessionError('Session expired');
|
||||
this.graphQLService.blockRequests(e);
|
||||
this.isNotifiedAboutExpiredSession = true;
|
||||
this.onSessionExpire.next();
|
||||
try {
|
||||
await this.commonDialogService.open(SessionExpiredDialog, null);
|
||||
} finally {
|
||||
const e = new SessionError('Session expired');
|
||||
this.graphQLService.blockRequests(e);
|
||||
this.notificationService.customNotification(() => ActionSnackbar, {
|
||||
actionText: 'app_root_session_expired_reload',
|
||||
onAction: () => location.reload(),
|
||||
}, { title: 'app_root_session_expired_title', persistent: true, type: ENotificationType.Error });
|
||||
}
|
||||
}
|
||||
throw exception;
|
||||
}
|
||||
@@ -7,3 +7,4 @@ export * from './ServerService';
|
||||
export * from './usePermission';
|
||||
export * from './ServerSettingsService';
|
||||
export * from './SessionSettingsService';
|
||||
export * from './SessionExpireService';
|
||||
|
||||
@@ -14,7 +14,8 @@ import { IResponseInterceptor } from './IResponseInterceptor';
|
||||
|
||||
export class CustomGraphQLClient extends GraphQLClient {
|
||||
private interceptors: IResponseInterceptor[] = [];
|
||||
private isRequestsBlockedData: { status: boolean; reason: Error | string } = { status: false, reason: '' };
|
||||
private isRequestsBlocked = false;
|
||||
private requestsBlockedReason?: Error | string;
|
||||
|
||||
constructor(endpoint: string) {
|
||||
super(endpoint);
|
||||
@@ -32,23 +33,24 @@ export class CustomGraphQLClient extends GraphQLClient {
|
||||
}
|
||||
|
||||
blockRequests(reason: Error | string): void {
|
||||
this.isRequestsBlockedData.status = true;
|
||||
this.isRequestsBlockedData.reason = reason;
|
||||
this.isRequestsBlocked = true;
|
||||
this.requestsBlockedReason = reason;
|
||||
}
|
||||
|
||||
blockRequestsReasonHandler(): void {
|
||||
if(this.isRequestsBlockedData.reason instanceof Error) {
|
||||
throw this.isRequestsBlockedData.reason;
|
||||
} else {
|
||||
throw new Error(this.isRequestsBlockedData.reason)
|
||||
private blockRequestsReasonHandler(): void {
|
||||
if(!this.isRequestsBlocked) {
|
||||
return;
|
||||
} else {
|
||||
if(this.requestsBlockedReason instanceof Error) {
|
||||
throw this.requestsBlockedReason;
|
||||
} else {
|
||||
throw new Error(this.requestsBlockedReason)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async overrideRequest<T>(query: string, variables?: Variables): Promise<T> {
|
||||
if(this.isRequestsBlockedData.status) {
|
||||
this.blockRequestsReasonHandler();
|
||||
}
|
||||
|
||||
this.blockRequestsReasonHandler();
|
||||
try {
|
||||
const response = await this.rawRequest<T>(query, variables);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user