fix: CB-884 handle network state change

This commit is contained in:
Wroud
2021-04-06 19:33:59 +03:00
parent fdc99d4b17
commit 3e2bcafcee
6 changed files with 112 additions and 2 deletions
@@ -78,6 +78,7 @@ import { LocalizationService } from '@cloudbeaver/core-localization';
import { PluginManagerService } from '@cloudbeaver/core-plugin';
import { ProductManagerService, ProductSettingsService } from '@cloudbeaver/core-product';
import {
NetworkStateService,
SessionService,
ServerService,
PermissionsService,
@@ -104,6 +105,7 @@ export const coreManifest: PluginManifest = {
providers: [
RouterService, // important, should be first because the router starts in load phase first after all plugins register phase
NetworkStateService,
AdministrationLocaleService,
AdministrationTopAppBarService,
AdministrationScreenService,
@@ -0,0 +1,15 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2021 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
export class NetworkError extends Error {
constructor(message: string) {
super(message);
this.name = 'NetworkError';
}
}
@@ -0,0 +1,78 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2021 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 { makeObservable, observable } from 'mobx';
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
import { Executor, IExecutor } from '@cloudbeaver/core-executor';
import { GraphQLService } from '@cloudbeaver/core-sdk';
import { NetworkError } from './NetworkError';
@injectable()
export class NetworkStateService extends Bootstrap {
get state(): boolean {
return this.networkState;
}
readonly networkStateExecutor: IExecutor<boolean>;
private networkState: boolean;
constructor(
private graphQLService: GraphQLService
) {
super();
makeObservable<NetworkStateService, 'networkState'>(this, {
networkState: observable,
});
this.networkState = true;
this.networkStateExecutor = new Executor();
}
register(): void {
this.networkState = window.navigator.onLine;
window.addEventListener('online', () => this.setState(true));
window.addEventListener('offline', () => this.setState(false));
this.graphQLService.registerInterceptor(this.sessionExpiredInterceptor.bind(this));
}
load(): void {}
private setState(state: boolean) {
if (this.networkState === state) {
return;
}
if (state) {
if (this.graphQLService.client.blockReason instanceof NetworkError) {
this.graphQLService.enableRequests();
}
} else {
this.graphQLService.blockRequests(new NetworkError('Network connection was lost'));
}
this.networkState = state;
this.networkStateExecutor.execute(this.networkState);
}
private async sessionExpiredInterceptor(request: Promise<any>): Promise<any> {
try {
return await request;
} catch (exception) {
if (
exception instanceof TypeError
&& exception.message === 'Failed to fetch'
) {
throw new NetworkError('Error while processing request');
}
throw exception;
}
}
}
+2
View File
@@ -1,4 +1,6 @@
export * from './ConnectionNavigatorViewSettings';
export * from './NetworkError';
export * from './NetworkStateService';
export * from './PermissionsResource';
export * from './PermissionsService';
export * from './ServerConfigResource';
@@ -13,9 +13,13 @@ import { GQLError } from './GQLError';
import type { IResponseInterceptor } from './IResponseInterceptor';
export class CustomGraphQLClient extends GraphQLClient {
get blockReason(): Error | string | null {
return this.requestsBlockedReason;
}
private interceptors: IResponseInterceptor[] = [];
private isRequestsBlocked = false;
private requestsBlockedReason?: Error | string;
private requestsBlockedReason: Error | string | null = null;
registerInterceptor(interceptor: IResponseInterceptor): void {
this.interceptors.push(interceptor);
@@ -28,6 +32,11 @@ export class CustomGraphQLClient extends GraphQLClient {
);
}
enableRequests(): void {
this.isRequestsBlocked = false;
this.requestsBlockedReason = null;
}
blockRequests(reason: Error | string): void {
this.isRequestsBlocked = true;
this.requestsBlockedReason = reason;
@@ -38,7 +47,7 @@ export class CustomGraphQLClient extends GraphQLClient {
if (this.requestsBlockedReason instanceof Error) {
throw this.requestsBlockedReason;
} else {
throw new Error(this.requestsBlockedReason);
throw new Error(this.requestsBlockedReason ?? undefined);
}
}
}
@@ -29,6 +29,10 @@ export class GraphQLService {
this.client.registerInterceptor(interceptor);
}
enableRequests(): void {
this.client.enableRequests();
}
blockRequests(reason: Error | string): void {
this.client.blockRequests(reason);
}