diff --git a/packages/platform/src/status.ts b/packages/platform/src/status.ts index f82a19fdb5..807a0d79ba 100644 --- a/packages/platform/src/status.ts +++ b/packages/platform/src/status.ts @@ -93,5 +93,8 @@ export function unknownStatus (message: string): Status<any> { * @public */ export function unknownError (err: unknown): Status { - return err instanceof PlatformError ? err.status : err instanceof Error ? unknownStatus(err.message) : ERROR + if (err instanceof PlatformError) return err.status + if (err instanceof Error) return unknownStatus(err.message) + if (typeof err === 'string') return unknownStatus(err) + return ERROR } diff --git a/packages/presentation/package.json b/packages/presentation/package.json index fbfd60b347..9ef5a3bb58 100644 --- a/packages/presentation/package.json +++ b/packages/presentation/package.json @@ -41,6 +41,7 @@ "dependencies": { "@hcengineering/platform": "^0.6.9", "@hcengineering/core": "^0.6.28", + "@hcengineering/analytics": "^0.6.0", "@hcengineering/query": "^0.6.8", "@hcengineering/ui": "^0.6.11", "@hcengineering/view": "^0.6.9", diff --git a/packages/presentation/src/pipeline.ts b/packages/presentation/src/pipeline.ts index fd15864042..13292fea32 100644 --- a/packages/presentation/src/pipeline.ts +++ b/packages/presentation/src/pipeline.ts @@ -1,3 +1,4 @@ +import { Analytics } from '@hcengineering/analytics' import { toFindResult, type Class, @@ -18,7 +19,7 @@ import { type TxResult, type WithLookup } from '@hcengineering/core' -import { type Resource } from '@hcengineering/platform' +import { setPlatformStatus, unknownError, type Resource } from '@hcengineering/platform' /** * @public @@ -112,9 +113,16 @@ export class PresentationPipelineImpl implements PresentationPipeline { query: DocumentQuery<T>, options?: FindOptions<T> ): Promise<FindResult<T>> { - return this.head !== undefined - ? await this.head.findAll(_class, query, options) - : await this.client.findAll(_class, query, options) + try { + return this.head !== undefined + ? await this.head.findAll(_class, query, options) + : await this.client.findAll(_class, query, options) + } catch (err) { + Analytics.handleError(err as Error) + const status = unknownError(err) + await setPlatformStatus(status) + return toFindResult([], -1) + } } async searchFulltext (query: SearchQuery, options: SearchOptions): Promise<SearchResult> { @@ -126,9 +134,15 @@ export class PresentationPipelineImpl implements PresentationPipeline { query: DocumentQuery<T>, options?: FindOptions<T> ): Promise<WithLookup<T> | undefined> { - return this.head !== undefined - ? await this.head.findOne(_class, query, options) - : await this.client.findOne(_class, query, options) + try { + return this.head !== undefined + ? await this.head.findOne(_class, query, options) + : await this.client.findOne(_class, query, options) + } catch (err) { + Analytics.handleError(err as Error) + const status = unknownError(err) + await setPlatformStatus(status) + } } async subscribe<T extends Doc>( @@ -147,15 +161,26 @@ export class PresentationPipelineImpl implements PresentationPipeline { } async tx (tx: Tx): Promise<TxResult> { - if (this.head === undefined) { - return await this.client.tx(tx) - } else { - return await this.head.tx(tx) + try { + if (this.head === undefined) { + return await this.client.tx(tx) + } else { + return await this.head.tx(tx) + } + } catch (err) { + Analytics.handleError(err as Error) + const status = unknownError(err) + await setPlatformStatus(status) + return {} } } async close (): Promise<void> { - await this.head?.close() + if (this.head !== undefined) { + await this.head.close() + return + } + await this.client.close() } } @@ -173,7 +198,11 @@ export abstract class BasePresentationMiddleware { } async provideClose (): Promise<void> { - await this.next?.close() + if (this.next !== undefined) { + await this.next.close() + return + } + await this.client.close() } async findAll<T extends Doc>( diff --git a/plugins/workbench-resources/src/components/WorkbenchApp.svelte b/plugins/workbench-resources/src/components/WorkbenchApp.svelte index 380610f339..a4caa38202 100644 --- a/plugins/workbench-resources/src/components/WorkbenchApp.svelte +++ b/plugins/workbench-resources/src/components/WorkbenchApp.svelte @@ -25,10 +25,11 @@ location, setMetadataLocalStorage } from '@hcengineering/ui' - import { connect, versionError } from '../connect' + import { connect, disconnect, versionError } from '../connect' import { workbenchId } from '@hcengineering/workbench' import workbench from '../plugin' + import { onDestroy } from 'svelte' const isNeedUpgrade = window.location.host === '' @@ -38,6 +39,8 @@ setMetadataLocalStorage(workbench.metadata.MobileAllowed, true) mobileAllowed = true } + + onDestroy(disconnect) </script> {#if $location.path[0] === workbenchId || $location.path[0] === workbench.component.WorkbenchApp} diff --git a/plugins/workbench-resources/src/connect.ts b/plugins/workbench-resources/src/connect.ts index 828c166d5f..d03893b78d 100644 --- a/plugins/workbench-resources/src/connect.ts +++ b/plugins/workbench-resources/src/connect.ts @@ -32,6 +32,14 @@ addEventListener(client.event.NetworkRequests, async (event: string, val: number networkStatus.set(val) }) +export async function disconnect (): Promise<void> { + if (_client !== undefined) { + await _client.close() + _client = undefined + _clientSet = false + } +} + export async function connect (title: string): Promise<Client | undefined> { const loc = getCurrentLocation() const ws = loc.path[1]