mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
fix: CB-884 handle network state change
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user