diff --git a/docs/api/cozy-client/classes/StackLink.md b/docs/api/cozy-client/classes/StackLink.md index 28869785a3..ad99609ed5 100644 --- a/docs/api/cozy-client/classes/StackLink.md +++ b/docs/api/cozy-client/classes/StackLink.md @@ -22,6 +22,7 @@ Transfers queries and mutations to a remote stack | :------ | :------ | :------ | | `[options]` | `Object` | Options | | `[options].client` | `any` | - | +| `[options].platform` | `any` | - | | `[options].stackClient` | `any` | - | *Overrides* @@ -30,17 +31,27 @@ Transfers queries and mutations to a remote stack *Defined in* -[packages/cozy-client/src/StackLink.js:62](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/StackLink.js#L62) +[packages/cozy-client/src/StackLink.js:64](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/StackLink.js#L64) ## Properties +### isOnline + +• **isOnline**: `any` + +*Defined in* + +[packages/cozy-client/src/StackLink.js:72](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/StackLink.js#L72) + +*** + ### stackClient • **stackClient**: `any` *Defined in* -[packages/cozy-client/src/StackLink.js:69](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/StackLink.js#L69) +[packages/cozy-client/src/StackLink.js:71](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/StackLink.js#L71) ## Methods @@ -62,7 +73,7 @@ Transfers queries and mutations to a remote stack *Defined in* -[packages/cozy-client/src/StackLink.js:118](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/StackLink.js#L118) +[packages/cozy-client/src/StackLink.js:132](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/StackLink.js#L132) *** @@ -82,7 +93,7 @@ Transfers queries and mutations to a remote stack *Defined in* -[packages/cozy-client/src/StackLink.js:95](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/StackLink.js#L95) +[packages/cozy-client/src/StackLink.js:109](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/StackLink.js#L109) *** @@ -107,7 +118,7 @@ Transfers queries and mutations to a remote stack *Defined in* -[packages/cozy-client/src/StackLink.js:87](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/StackLink.js#L87) +[packages/cozy-client/src/StackLink.js:101](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/StackLink.js#L101) *** @@ -127,7 +138,7 @@ Transfers queries and mutations to a remote stack *Defined in* -[packages/cozy-client/src/StackLink.js:72](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/StackLink.js#L72) +[packages/cozy-client/src/StackLink.js:75](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/StackLink.js#L75) *** @@ -153,7 +164,7 @@ Transfers queries and mutations to a remote stack *Defined in* -[packages/cozy-client/src/StackLink.js:80](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/StackLink.js#L80) +[packages/cozy-client/src/StackLink.js:83](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/StackLink.js#L83) *** @@ -167,4 +178,4 @@ Transfers queries and mutations to a remote stack *Defined in* -[packages/cozy-client/src/StackLink.js:76](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/StackLink.js#L76) +[packages/cozy-client/src/StackLink.js:79](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/StackLink.js#L79) diff --git a/packages/cozy-client/src/StackLink.js b/packages/cozy-client/src/StackLink.js index e414c2b88b..038511a66e 100644 --- a/packages/cozy-client/src/StackLink.js +++ b/packages/cozy-client/src/StackLink.js @@ -5,6 +5,7 @@ import CozyLink from './CozyLink' import { DOCTYPE_FILES } from './const' import { BulkEditError } from './errors' import logger from './logger' +import { isReactNativeOfflineError } from './utils' /** * @@ -58,8 +59,9 @@ export default class StackLink extends CozyLink { * @param {object} [options] - Options * @param {object} [options.stackClient] - A StackClient * @param {object} [options.client] - A StackClient (deprecated) + * @param {import('cozy-pouch-link/dist/types').LinkPlatform} [options.platform] Platform specific adapters and methods */ - constructor({ client, stackClient } = {}) { + constructor({ client, stackClient, platform } = {}) { super() if (client) { logger.warn( @@ -67,6 +69,7 @@ export default class StackLink extends CozyLink { ) } this.stackClient = stackClient || client + this.isOnline = platform?.isOnline } registerClient(client) { @@ -77,11 +80,22 @@ export default class StackLink extends CozyLink { this.stackClient = null } - request(operation, result, forward) { - if (operation.mutationType) { - return this.executeMutation(operation, result, forward) + async request(operation, result, forward) { + if (this.isOnline && !(await this.isOnline())) { + return forward(operation) + } + + try { + if (operation.mutationType) { + return await this.executeMutation(operation, result, forward) + } + return await this.executeQuery(operation) + } catch (err) { + if (isReactNativeOfflineError(err)) { + return forward(operation) + } + throw err } - return this.executeQuery(operation) } async persistData(data, forward) { diff --git a/packages/cozy-client/src/utils.js b/packages/cozy-client/src/utils.js index 973ac5cf37..8ac4fe55b3 100644 --- a/packages/cozy-client/src/utils.js +++ b/packages/cozy-client/src/utils.js @@ -68,3 +68,15 @@ export const hasQueriesBeenLoaded = queriesResults => { hasQueryBeenLoaded(queryResult) ) } + +/** + * Check is the error is about ReactNative not having access to internet + * + * @param {Error} err - The error to check + * @returns {boolean} True if the error is a network error, otherwise false + */ +export const isReactNativeOfflineError = err => { + // This error message is specific to ReactNative + // Network errors on a browser would produce another error.message + return err.message === 'Network request failed' +} diff --git a/packages/cozy-client/types/StackLink.d.ts b/packages/cozy-client/types/StackLink.d.ts index 80a4d6d97e..839117535d 100644 --- a/packages/cozy-client/types/StackLink.d.ts +++ b/packages/cozy-client/types/StackLink.d.ts @@ -9,12 +9,15 @@ export default class StackLink extends CozyLink { * @param {object} [options] - Options * @param {object} [options.stackClient] - A StackClient * @param {object} [options.client] - A StackClient (deprecated) + * @param {import('cozy-pouch-link/dist/types').LinkPlatform} [options.platform] Platform specific adapters and methods */ - constructor({ client, stackClient }?: { + constructor({ client, stackClient, platform }?: { stackClient: object; client: object; + platform: import('cozy-pouch-link/dist/types').LinkPlatform; }); stackClient: any; + isOnline: any; registerClient(client: any): void; reset(): void; /** diff --git a/packages/cozy-client/types/utils.d.ts b/packages/cozy-client/types/utils.d.ts index 031006d18c..603dfc0ac6 100644 --- a/packages/cozy-client/types/utils.d.ts +++ b/packages/cozy-client/types/utils.d.ts @@ -2,6 +2,7 @@ export function isQueryLoading(col: any): boolean; export function hasQueryBeenLoaded(col: any): any; export function isQueriesLoading(queriesResults: any): boolean; export function hasQueriesBeenLoaded(queriesResults: any): boolean; +export function isReactNativeOfflineError(err: Error): boolean; export type CancelablePromise = Promise; /** * @typedef {Promise} CancelablePromise